Mmore of the code cldeanup handle. It was less fun than it looked.
authorRobert Lipe <robertlipe@gpsbabel.org>
Mon, 13 Nov 2017 09:50:09 +0000 (03:50 -0600)
committerRobert Lipe <robertlipe@gpsbabel.org>
Mon, 13 Nov 2017 09:50:09 +0000 (03:50 -0600)
30 files changed:
igc.cc
ignrando.cc
igo8.cc
ik3d.cc
interpolate.cc
itracku.cc
jogmap.cc
jtr.cc
kml.cc
lmx.cc
lowranceusr.cc
lowranceusr4.cc
maggeo.cc
mapasia.cc
mapbar_track.cc
mapfactor.cc
mapsend.cc
mmo.cc
mtk_locus.cc
mtk_logger.cc
mynav.cc
navicache.cc
naviguide.cc
navilink.cc
navitel.cc
netstumbler.cc
nmea.cc
nmea_.cc [new file with mode: 0644]
nmn4.cc
nukedata.cc

diff --git a/igc.cc b/igc.cc
index a501363c23e578d615e2c54862795f889a6694a7..03b51e9bb8412338d70dbd0080269960bb622139 100644 (file)
--- a/igc.cc
+++ b/igc.cc
@@ -935,7 +935,7 @@ static arglist_t igc_args[] = {
   {
     "timeadj", &timeadj,
     "(integer sec or 'auto') Barograph to GPS time diff",
-    NULL, ARGTYPE_STRING, ARG_NOMINMAX
+    NULL, ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   ARG_TERMINATOR
 };
@@ -952,4 +952,6 @@ ff_vecs_t igc_vecs = {
   NULL,
   igc_args,
   CET_CHARSET_ASCII, 0 /* CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
index 79e44067adba6073dea710828fc48ebaf54c353e..5de8c12f0146f0c26dfe72e17066a6628585573b 100644 (file)
@@ -39,7 +39,7 @@ static int xmlpoints;
 static char* index_opt = NULL;
 
 static arglist_t ignr_args[] = {
-  {"index", &index_opt, "Index of track to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL },
+  {"index", &index_opt, "Index of track to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL , nullptr},
   ARG_TERMINATOR
 };
 
@@ -76,7 +76,7 @@ static xg_callback    ignr_nb_etapes, ignr_descr;
 static xg_callback     ignr_etape_begin, ignr_etape_end;
 
 static void
-ignr_start(xg_string args, const QXmlStreamAttributes* attrv)
+ignr_start(xg_string, const QXmlStreamAttributes*)
 {
   ignr_xml_error((track != NULL));
 
@@ -85,20 +85,20 @@ ignr_start(xg_string args, const QXmlStreamAttributes* attrv)
 }
 
 static void
-ignr_nb_etapes(xg_string args, const QXmlStreamAttributes* attrv)
+ignr_nb_etapes(xg_string args, const QXmlStreamAttributes*)
 {
   xmlpoints = args.toInt();
 }
 
 static void
-ignr_descr(xg_string args, const QXmlStreamAttributes* attrv)
+ignr_descr(xg_string args, const QXmlStreamAttributes*)
 {
   ignr_xml_error((track == NULL));
   track->rte_desc = args;
 }
 
 static void
-ignr_etape_begin(xg_string args, const QXmlStreamAttributes* attrv)
+ignr_etape_begin(xg_string, const QXmlStreamAttributes*)
 {
   ignr_xml_error((wpt != NULL));
 
@@ -106,7 +106,7 @@ ignr_etape_begin(xg_string args, const QXmlStreamAttributes* attrv)
 }
 
 static void
-ignr_etape_end(xg_string args, const QXmlStreamAttributes* attrv)
+ignr_etape_end(xg_string, const QXmlStreamAttributes*)
 {
   ignr_xml_error((track == NULL) || (wpt == NULL));
 
@@ -115,7 +115,7 @@ ignr_etape_end(xg_string args, const QXmlStreamAttributes* attrv)
 }
 
 static void
-ignr_etape_pos(xg_string args, const QXmlStreamAttributes* attrv)
+ignr_etape_pos(xg_string args, const QXmlStreamAttributes*)
 {
   ignr_xml_error((wpt == NULL) || (args.isEmpty()));
 
@@ -125,7 +125,7 @@ ignr_etape_pos(xg_string args, const QXmlStreamAttributes* attrv)
 }
 
 static void
-ignr_etape_alt(xg_string args, const QXmlStreamAttributes* attrv)
+ignr_etape_alt(xg_string args, const QXmlStreamAttributes*)
 {
   ignr_xml_error((wpt == NULL));
   if (args == NULL) {
@@ -193,7 +193,7 @@ ignr_write_track_hdr(const route_head* track)
 }
 
 static void
-ignr_write_track_trl(const route_head* track)
+ignr_write_track_trl(const route_head*)
 {
 }
 
@@ -260,4 +260,6 @@ ff_vecs_t ignr_vecs = {
   NULL,
   ignr_args,
   CET_CHARSET_MS_ANSI, 1
+  , NULL_POS_OPS,
+  nullptr
 };
diff --git a/igo8.cc b/igo8.cc
index 85937e2eb729ebc665e15a9444de9ff45140dbb0..468169c773b77fc3c82f76a5cf0fcce0017d3b4f 100644 (file)
--- a/igo8.cc
+++ b/igo8.cc
@@ -106,9 +106,9 @@ static int in_point_count;
 
 // Exported options list
 static arglist_t igo8_options[] = {
-  { "tracknum", &igo8_option_tracknum, "Track identification number", NULL, ARGTYPE_INT, ARG_NOMINMAX },
-  { "title", &igo8_option_title, "Track title", NULL, ARGTYPE_STRING, ARG_NOMINMAX },
-  { "description", &igo8_option_description, "Track description", NULL, ARGTYPE_STRING, ARG_NOMINMAX },
+  { "tracknum", &igo8_option_tracknum, "Track identification number", NULL, ARGTYPE_INT, ARG_NOMINMAX, nullptr },
+  { "title", &igo8_option_title, "Track title", NULL, ARGTYPE_STRING, ARG_NOMINMAX, nullptr },
+  { "description", &igo8_option_description, "Track description", NULL, ARGTYPE_STRING, ARG_NOMINMAX, nullptr },
   ARG_TERMINATOR
 };
 
@@ -367,4 +367,6 @@ ff_vecs_t igo8_vecs = {
   igo8_options,
   CET_CHARSET_UTF8,
   1
+  , NULL_POS_OPS,
+  nullptr
 };
diff --git a/ik3d.cc b/ik3d.cc
index 37042437dc4c45382de9e416bd81ccfd6c79b3be..6828d45ab51af99997ad8396c72a9cf7f8261f0a 100644 (file)
--- a/ik3d.cc
+++ b/ik3d.cc
@@ -72,7 +72,7 @@ ikt_object_end(void)
 }
 
 static void
-iktobj_waypt(xg_string args, const QXmlStreamAttributes* attrv)
+iktobj_waypt(xg_string, const QXmlStreamAttributes* attrv)
 {
   if (attrv->hasAttribute("X")) {
     waypt->longitude = attrv->value("X").toString().toDouble();
@@ -159,4 +159,6 @@ ff_vecs_t ik3d_vecs = {
   NULL,
   ikt_args,
   CET_CHARSET_UTF8, 1
+  , NULL_POS_OPS,
+  nullptr
 };
index 498a5a1afe5e962b6e5bd1689dac42d6719c1291..2f1a27eeedf9f90ff579c7be521a80308fa90496 100644 (file)
@@ -38,22 +38,22 @@ arglist_t interpfilt_args[] = {
   {
     "time", &opt_interval, "Time interval in seconds", NULL,
     ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_INT,
-    "0", NULL
+    "0", NULL, nullptr
   },
   {
     "distance", &opt_dist, "Distance interval in miles or kilometers",
     NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_STRING,
-    ARG_NOMINMAX
+    ARG_NOMINMAX, nullptr
   },
   {
     "route", &opt_route, "Interpolate routes instead", NULL,
-    ARGTYPE_BOOL, ARG_NOMINMAX
+    ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   ARG_TERMINATOR
 };
 
 void
-interpfilt_process(void)
+interpfilt_process()
 {
   queue* backuproute = NULL;
   queue* elem, *tmp, *elem2, *tmp2;
@@ -173,7 +173,7 @@ interpfilt_process(void)
 }
 
 void
-interpfilt_init(const char* args)
+interpfilt_init(const char*)
 {
 
   char* fm;
index 15dbbfbce4d2712ae0841ad4bf3496e4f4463d34..cf96c7d63b9ee8965e6833afc796c089c8616378 100644 (file)
@@ -354,8 +354,8 @@ init_device()
 // select the type of option.
 static
 arglist_t itracku_args[] = {
-  { "backup", &backup_file_name, "Appends the input to a backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX },
-  { "new", &only_new, "Only waypoints that are not the backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX },
+  { "backup", &backup_file_name, "Appends the input to a backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX, nullptr},
+  { "new", &only_new, "Only waypoints that are not the backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX, nullptr },
 //   "default", ARGYTPE_STRING, ARG_NOMINMAX} ,
   ARG_TERMINATOR
 };
@@ -365,7 +365,7 @@ arglist_t itracku_args[] = {
 *******************************************************************************/
 
 static void
-itracku_rd_init_common(const QString& fname)
+itracku_rd_init_common(const QString&)
 {
   new_waypoint_count = 0;
 
@@ -743,7 +743,7 @@ gprmc_parse(char* ibuf)
        andreas.grimme@gmx.net
 */
 static Waypoint*
-itracku_rt_position(posn_status* posn_status)
+itracku_rt_position(posn_status*)
 {
   char line[1024];
   Waypoint* wpt;
@@ -785,7 +785,8 @@ ff_vecs_t itracku_vecs = {
   itracku_args,
   CET_CHARSET_ASCII, 0, /* ascii is the expected character set */
   /* not fixed, can be changed through command line parameter */
-  { itracku_rt_init, itracku_rt_position, itracku_rt_deinit, NULL, NULL, NULL }
+  { itracku_rt_init, itracku_rt_position, itracku_rt_deinit, NULL, NULL, NULL },
+  nullptr
 };
 
 ff_vecs_t itracku_fvecs = {
@@ -805,7 +806,8 @@ ff_vecs_t itracku_fvecs = {
   itracku_args,
   CET_CHARSET_ASCII, 0, /* ascii is the expected character set */
   /* not fixed, can be changed through command line parameter */
-  { NULL, NULL, NULL, NULL, NULL, NULL }
+  { NULL, NULL, NULL, NULL, NULL, NULL },
+  nullptr
 };
 
 
index ef702370c3f3cbb7a87610a467ac23fa17da5b68..37c821f6f4c2d3e0a1ce3e439cbbf0dc3b78d028 100644 (file)
--- a/jogmap.cc
+++ b/jogmap.cc
@@ -43,14 +43,14 @@ static arglist_t jogmap_args[] = {
 
 
 static void
-jogmap_markers(xg_string args, const QXmlStreamAttributes* attrv)
+jogmap_markers(xg_string, const QXmlStreamAttributes*)
 {
   trk = route_head_alloc();
   track_add_head(trk);
 }
 
 static void
-jogmap_marker(xg_string args, const QXmlStreamAttributes* attrv)
+jogmap_marker(xg_string, const QXmlStreamAttributes* attrv)
 {
   Waypoint* wpt = new Waypoint;
 
@@ -82,13 +82,13 @@ jogmap_rd_init(const QString& fname)
 }
 
 static void
-jogmap_read(void)
+jogmap_read()
 {
   xml_read();
 }
 
 static void
-jogmap_rd_deinit(void)
+jogmap_rd_deinit()
 {
   xml_deinit();
 }
@@ -109,4 +109,6 @@ ff_vecs_t jogmap_vecs = {
   NULL,
   jogmap_args,
   CET_CHARSET_UTF8, 0
+  , NULL_POS_OPS,
+  nullptr
 };
diff --git a/jtr.cc b/jtr.cc
index e17a3bf805dbd07fa13e642c44a4991e7fab6e89..95e6dfaade7bde3f0e9571c2b7a27d7594f3c442 100644 (file)
--- a/jtr.cc
+++ b/jtr.cc
@@ -342,6 +342,8 @@ ff_vecs_t jtr_vecs = {
   jtr_args,
   CET_CHARSET_ASCII, 0                 /* ascii is the expected character set */
   /* not fixed, can be changed through command line parameter */
+  , NULL_POS_OPS,
+  nullptr
 };
 
 /**************************************************************************/
diff --git a/kml.cc b/kml.cc
index d55110c472cb2a4614ea591138b231609bd65935..d8871d3cca72c5dea5bd8c8489de9ac685997824 100644 (file)
--- a/kml.cc
+++ b/kml.cc
@@ -108,76 +108,76 @@ static const char kmt_power[] = "power";
 
 static
 arglist_t kml_args[] = {
-  {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX },
+  {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX, nullptr },
   {
     "lines", &opt_export_lines,
     "Export linestrings for tracks and routes",
-    "1", ARGTYPE_BOOL, ARG_NOMINMAX
+    "1", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr,
   },
   {
     "points", &opt_export_points,
     "Export placemarks for tracks and routes",
-    "1", ARGTYPE_BOOL, ARG_NOMINMAX
+    "1", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "line_width", &opt_line_width,
     "Width of lines, in pixels",
-    "6", ARGTYPE_INT, ARG_NOMINMAX
+    "6", ARGTYPE_INT, ARG_NOMINMAX, nullptr
   },
   {
     "line_color", &opt_line_color,
     "Line color, specified in hex AABBGGRR",
-    "99ffac59", ARGTYPE_STRING, ARG_NOMINMAX
+    "99ffac59", ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   {
     "floating", &opt_floating,
     "Altitudes are absolute and not clamped to ground",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX
+    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "extrude", &opt_extrude,
     "Draw extrusion line from trackpoint to ground",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX
+    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "track", &opt_export_track,
     "Write KML track (default = 0)",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX
+    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "trackdata", &opt_trackdata,
     "Include extended data for trackpoints (default = 1)",
-    "1", ARGTYPE_BOOL, ARG_NOMINMAX
+    "1", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "trackdirection", &opt_trackdirection,
     "Indicate direction of travel in track icons (default = 0)",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX
+    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "units", &opt_units,
     "Units used when writing comments ('s'tatute, 'm'etric,' 'n'autical, 'a'viation)",
-    "s", ARGTYPE_STRING, ARG_NOMINMAX
+    "s", ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   {
     "labels", &opt_labels,
     "Display labels on track and routepoints  (default = 1)",
-    "1", ARGTYPE_BOOL, ARG_NOMINMAX
+    "1", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "max_position_points", &opt_max_position_points,
     "Retain at most this number of position points  (0 = unlimited)",
-    "0", ARGTYPE_INT, ARG_NOMINMAX
+    "0", ARGTYPE_INT, ARG_NOMINMAX, nullptr
   },
   {
     "rotate_colors", &opt_rotate_colors,
     "Rotate colors for tracks and routes (default automatic)",
-    NULL, ARGTYPE_FLOAT, "0", "360"
+    NULL, ARGTYPE_FLOAT, "0", "360", nullptr
   },
   {
     "prec", &opt_precision,
     "Precision of coordinates, number of decimals",
-    DEFAULT_PRECISION, ARGTYPE_INT, ARG_NOMINMAX
+    DEFAULT_PRECISION, ARGTYPE_INT, ARG_NOMINMAX, nullptr
   },
   ARG_TERMINATOR
 };
diff --git a/lmx.cc b/lmx.cc
index b73bedee9c9ca24eddb6983093ca119b8a802905..c5af80c0587c1ef66bf4d5244f40a52eca3a0640 100644 (file)
--- a/lmx.cc
+++ b/lmx.cc
@@ -44,7 +44,7 @@ arglist_t lmx_args[] = {
   {
     "binary", &binary,
     "Compact binary representation",
-    NULL, ARGTYPE_BOOL, ARG_NOMINMAX
+    NULL, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   ARG_TERMINATOR
 };
@@ -336,13 +336,13 @@ lmx_rd_deinit(void)
 
 
 static void
-lmx_lm_start(xg_string args, const QXmlStreamAttributes*)
+lmx_lm_start(xg_string, const QXmlStreamAttributes*)
 {
   wpt_tmp = new Waypoint;
 }
 
 static void
-lmx_lm_end(xg_string args, const QXmlStreamAttributes*)
+lmx_lm_end(xg_string, const QXmlStreamAttributes*)
 {
   waypt_add(wpt_tmp);
 }
@@ -378,7 +378,7 @@ lmx_lm_desc(xg_string args, const QXmlStreamAttributes*)
 }
 
 static void
-lmx_lm_mlink_s(xg_string args, const QXmlStreamAttributes*)
+lmx_lm_mlink_s(xg_string, const QXmlStreamAttributes*)
 {
   urllink = urllinkt = QString();
 }
@@ -396,7 +396,7 @@ lmx_lm_linkt(xg_string args, const QXmlStreamAttributes*)
 }
 
 static void
-lmx_lm_mlink_e(xg_string args, const QXmlStreamAttributes*)
+lmx_lm_mlink_e(xg_string, const QXmlStreamAttributes*)
 {
   waypt_add_url(wpt_tmp, urllink, urllinkt);
 }
@@ -418,4 +418,6 @@ ff_vecs_t lmx_vecs = {
   NULL,
   lmx_args,
   CET_CHARSET_UTF8, 0  /* CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
index 653b07ddb4c2a3fa99e54911b77dfc6100743c0d..ae3529bf2623440ca07f0b1d34e1be80a4be03f2 100644 (file)
@@ -302,23 +302,23 @@ static
 arglist_t lowranceusr_args[] = {
   {
     "ignoreicons", &ignoreicons, "Ignore event marker icons on read",
-    NULL, ARGTYPE_BOOL, ARG_NOMINMAX
+    NULL, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "writeasicons", &writeasicons, "Treat waypoints as icons on write",
-    NULL, ARGTYPE_BOOL, ARG_NOMINMAX
+    NULL, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "merge", &merge, "(USR output) Merge into one segmented track",
-    NULL, ARGTYPE_BOOL, ARG_NOMINMAX
+    NULL, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "break", &seg_break, "(USR input) Break segments into separate tracks",
-    NULL, ARGTYPE_BOOL, ARG_NOMINMAX
+    NULL, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "wversion", &wversion_arg, "(USR output) Write version",
-    "2", ARGTYPE_INT, "2", "3"
+    "2", ARGTYPE_INT, "2", "3", nullptr
   },
   ARG_TERMINATOR
 };
@@ -980,7 +980,7 @@ lowranceusr_merge_track_hdr(const route_head* trk)
 }
 
 static void
-lowranceusr_merge_track_tlr(const route_head* trk)
+lowranceusr_merge_track_tlr(const route_head*)
 {
   short num_trail_points, max_trail_size;
   char visible=1;
@@ -1005,7 +1005,7 @@ lowranceusr_merge_track_tlr(const route_head* trk)
 }
 static void
 
-lowranceusr_merge_track_hdr_2(const route_head* trk)
+lowranceusr_merge_track_hdr_2(const route_head*)
 {
   continuous = 0;
 }
@@ -1098,4 +1098,6 @@ ff_vecs_t lowranceusr_vecs = {
   NULL,
   lowranceusr_args,
   CET_CHARSET_ASCII, 0 /* CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
index 53436d8be5dd5ef571b615de5e33a5dc7bdf1bce..8a6263a7add31a3599dad47e4da579c03dbbf846 100644 (file)
@@ -145,15 +145,15 @@ static
 arglist_t lowranceusr4_args[] = {
   {
     "title", &opt_title, "(output) Output title string",
-    "", ARGTYPE_STRING, ARG_NOMINMAX
+    "", ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   {
     "serialnum", &opt_serialnum, "(output) Device serial number",
-    "0", ARGTYPE_INT, ARG_NOMINMAX
+    "0", ARGTYPE_INT, ARG_NOMINMAX, nullptr
   },
   {
     "description", &opt_content_descr, "(output) Content description",
-    "", ARGTYPE_STRING, ARG_NOMINMAX
+    "", ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   ARG_TERMINATOR
 };
@@ -165,7 +165,7 @@ rd_init(const QString& fname)
 }
 
 static void
-rd_deinit(void)
+rd_deinit()
 {
   gbfclose(file_in);
 }
@@ -178,7 +178,7 @@ wr_init(const QString& fname)
 }
 
 static void
-wr_deinit(void)
+wr_deinit()
 {
   gbfclose(file_out);
   mkshort_del_handle(&mkshort_handle);
@@ -268,7 +268,7 @@ lowranceusr4_free_fsdata(void* fsdata)
 
 static
 lowranceusr4_fsdata*
-lowranceusr4_alloc_fsdata(void)
+lowranceusr4_alloc_fsdata()
 {
   lowranceusr4_fsdata* fsdata = (lowranceusr4_fsdata*) xcalloc(sizeof(*fsdata), 1);
   fsdata->fs.type = FS_LOWRANCEUSR4;
@@ -345,7 +345,7 @@ lowranceusr4_find_waypt_index(const Waypoint* wpt)
 
 
 static void
-lowranceusr4_parse_waypoints(void)
+lowranceusr4_parse_waypoints()
 {
   short int icon_num;
   unsigned int i, num_waypts, create_date, create_time;
@@ -505,7 +505,7 @@ lowranceusr4_find_waypt(int uid_unit, int uid_seq_low, int uid_seq_high)
 }
 
 static void
-lowranceusr4_parse_routes(void)
+lowranceusr4_parse_routes()
 {
   unsigned int num_routes, i, j, text_len;
   unsigned int num_legs;
@@ -583,7 +583,7 @@ lowranceusr4_parse_routes(void)
 }
 
 static void
-lowranceusr4_parse_trails(void)
+lowranceusr4_parse_trails()
 {
   int num_trails, num_trail_pts, M, i, j, k, trk_num, text_len;
   char buff[MAXUSRSTRINGSIZE + 1];
@@ -724,7 +724,7 @@ lowranceusr4_parse_trails(void)
 
 
 static void
-data_read(void)
+data_read()
 {
   short int MajorVersion, MinorVersion;
   int text_len, DataStreamVersion;
@@ -839,7 +839,7 @@ lowranceusr4_waypt_disp(const Waypoint* wpt)
 }
 
 static void
-lowranceusr4_write_waypoints(void)
+lowranceusr4_write_waypoints()
 {
   int i;
 
@@ -914,14 +914,14 @@ lowranceusr4_write_wpt_uids(const Waypoint* wpt)
 }
 
 static void
-lowranceusr4_write_route_trl(const route_head* rte)
+lowranceusr4_write_route_trl(const route_head*)
 {
   /* Mystery byte */
   gbfputc(0, file_out);
 }
 
 static void
-lowranceusr4_write_routes(void)
+lowranceusr4_write_routes()
 {
   if (global_opts.debug_level >= 1) {
     printf(MYNAME " writing %d routes\n", route_count());
@@ -1007,7 +1007,7 @@ lowranceusr4_write_track_waypt(const Waypoint* wpt)
 }
 
 static void
-lowranceusr4_write_trails(void)
+lowranceusr4_write_trails()
 {
   if (global_opts.debug_level >= 1) {
     printf(MYNAME " writing %d tracks\n", track_count());
@@ -1018,7 +1018,7 @@ lowranceusr4_write_trails(void)
 }
 
 static void
-data_write(void)
+data_write()
 {
   short int MajorVersion, MinorVersion;
   int DataStreamVersion;
@@ -1077,4 +1077,6 @@ ff_vecs_t lowranceusr4_vecs = {
   NULL,
   lowranceusr4_args,
   CET_CHARSET_ASCII, 0 /* CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
index 9bf92bb1b002e2b558fec938204783d6b4901c00..205b5d875c48f036886b5400b48b64475d45770c 100644 (file)
--- a/maggeo.cc
+++ b/maggeo.cc
@@ -339,4 +339,6 @@ ff_vecs_t maggeo_vecs = {
 #else
   CET_CHARSET_ASCII, 0 /* CET-REVIEW */
 #endif
+  , NULL_POS_OPS,
+  nullptr
 };
index 8ca0ef98cd55e571276e96208433ad60599dfa38..29a43d3b0a13d6c4dc2635a80b9df6e808cf367b 100644 (file)
@@ -67,7 +67,7 @@ tr7_rd_init(const QString& fname)
 }
 
 static void
-tr7_read(void)
+tr7_read()
 {
   route_head* trk = NULL;
   unsigned int magic;
@@ -185,7 +185,7 @@ tr7_check_after_read_trailer_cb(const route_head* trk)
 }
 
 static void
-tr7_rd_deinit(void)
+tr7_rd_deinit()
 {
   track_disp_session(curr_session(),
                      tr7_check_after_read_head_cb,
@@ -199,7 +199,7 @@ tr7_rd_deinit(void)
 *******************************************************************************/
 
 static void
-tr7_disp_track_head_cb(const route_head* trk)
+tr7_disp_track_head_cb(const route_head*)
 {
   wpt_tmp = NULL;
 }
@@ -270,13 +270,13 @@ tr7_wr_init(const QString& fname)
 }
 
 static void
-tr7_wr_deinit(void)
+tr7_wr_deinit()
 {
   gbfclose(fout);
 }
 
 static void
-tr7_write(void)
+tr7_write()
 {
   track_disp_all(tr7_disp_track_head_cb, NULL, tr7_disp_waypt_cb);
 }
@@ -299,6 +299,8 @@ ff_vecs_t mapasia_tr7_vecs = {              /* we can read and write tracks */
   NULL,
   tr7_args,
   CET_CHARSET_UTF8, 1  /* FIXED - CET-REVIEW - */
+  , NULL_POS_OPS,
+  nullptr
 
 };
 
index 7bb249f2661497534313422f24c0658f0d51539b..4b1a501dc5ecafdf9f180e8f04248b4e22cac4dd 100644 (file)
@@ -138,4 +138,6 @@ ff_vecs_t mapbar_track_vecs = {
   mapbar_track_args,
   CET_CHARSET_UTF8, 0
   /* not fixed, can be changed through command line parameter */
+  , NULL_POS_OPS,
+  nullptr
 };
index 6b478f450aa9cb1dc2eb646235cc5a8ddd74f46c..0b1b5dfe4b5a65c6d52af4be108586e9d8bf8119 100644 (file)
@@ -158,4 +158,6 @@ ff_vecs_t mapfactor_vecs = {
   NULL,
   mapfactor_args,
   CET_CHARSET_UTF8, 0  /* CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
index fec6ef5c1fb3ffb6b64146fb9475287c20c75617..ffbb03b03046c44728a2215b24b1aa69be1d780e 100644 (file)
@@ -45,7 +45,7 @@ arglist_t mapsend_args[] = {
   {
     "trkver", &mapsend_opt_trkver,
     "MapSend version TRK file to generate (3,4)",
-    "4", ARGTYPE_INT, "3", "4"
+    "4", ARGTYPE_INT, "3", "4", nullptr
   },
   ARG_TERMINATOR
 };
@@ -79,7 +79,7 @@ mapsend_rd_init(const QString& fname)
 }
 
 static void
-mapsend_rd_deinit(void)
+mapsend_rd_deinit()
 {
   gbfclose(mapsend_file_in);
 }
@@ -99,7 +99,7 @@ mapsend_wr_init(const QString& fname)
 }
 
 static void
-mapsend_wr_deinit(void)
+mapsend_wr_deinit()
 {
   gbfclose(mapsend_file_out);
   mkshort_del_handle(&mkshort_handle);
@@ -107,7 +107,7 @@ mapsend_wr_deinit(void)
 }
 
 static void
-mapsend_wpt_read(void)
+mapsend_wpt_read()
 {
   char tbuf[256];
   int wpt_count, rte_count, rte_num;
@@ -188,7 +188,7 @@ mapsend_wpt_read(void)
 }
 
 static void
-mapsend_track_read(void)
+mapsend_track_read()
 {
   unsigned int trk_count;
   int valid;
@@ -232,7 +232,7 @@ mapsend_track_read(void)
 }
 
 static void
-mapsend_read(void)
+mapsend_read()
 {
   mapsend_hdr hdr;
   int type;
@@ -367,7 +367,7 @@ mapsend_route_hdr(const route_head* rte)
 }
 
 static void
-mapsend_noop(const route_head* wp)
+mapsend_noop(const route_head*)
 {
   /* no-op */
 }
@@ -503,13 +503,13 @@ void mapsend_track_disp(const Waypoint* wpt)
 }
 
 void
-mapsend_track_write(void)
+mapsend_track_write()
 {
   track_disp_all(mapsend_track_hdr, mapsend_noop, mapsend_track_disp);
 }
 
 static void
-mapsend_wpt_write(void)
+mapsend_wpt_write()
 {
   mapsend_hdr hdr = {13, {'4','D','5','3','3','3','3','0',' ','M','S'},
     {'3', '0'}, ms_type_wpt, {0, 0, 0}
@@ -558,4 +558,6 @@ ff_vecs_t mapsend_vecs = {
   NULL,
   mapsend_args,
   CET_CHARSET_ASCII, 0 /* CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
diff --git a/mmo.cc b/mmo.cc
index 3c0d617269bdf6fb26e091d22a2cec5f7cd21f04..38f1d7e690bbb8ea1fa940d15bd200e05fdc774c 100644 (file)
--- a/mmo.cc
+++ b/mmo.cc
@@ -36,15 +36,15 @@ static
 arglist_t mmo_args[] = {
   {
     "locked", &opt_locked, "Write items 'locked' [default no]", "0",
-    ARGTYPE_BOOL, ARG_NOMINMAX
+    ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "visible", &opt_visible, "Write items 'visible' [default yes]", "1",
-    ARGTYPE_BOOL, ARG_NOMINMAX
+    ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "ver", &opt_version, "Write files with internal version [n]", NULL,
-    ARGTYPE_INT, "17", "18"
+    ARGTYPE_INT, "17", "18", nullptr
   },
   ARG_TERMINATOR
 };
@@ -221,10 +221,10 @@ mmo_fillbuf2(void* buf, const gbsize_t bufsz, const gbsize_t count, const int ne
 }
 #define mmo_fillbuf(a,b,c) mmo_fillbuf2((a),sizeof((a)),(b),(c))
 
+#ifdef MMO_DBG
 static void
 mmo_printbuf(const char* buf, int count, const char* comment)
 {
-#ifdef MMO_DBG
   int i;
   printf("%s", comment);
   for (i = 0; i < count; i++) {
@@ -239,8 +239,8 @@ mmo_printbuf(const char* buf, int count, const char* comment)
     }
   printf("\n");
   fflush(stdout);
-#endif
 }
+#endif
 
 /******************************************************************************/
 
@@ -341,8 +341,9 @@ mmo_end_of_route(mmo_data_t* data)
   if (mmo_version >= 0x12) {
     mmo_fillbuf(buf, 7, 1);
     DBG((sobj, "route data (since 0x12): "));
+#ifdef MMO_DBG
     mmo_printbuf(buf, 7, "");
-
+#endif
     rte->line_color.bbggrr = le_read32(&buf[0]);
     rte->line_color.opacity = 255 - (buf[6] * 51);
     DBG((sobj, "color = 0x%06X\n", rte->line_color.bbggrr));
@@ -378,6 +379,7 @@ mmo_read_category(mmo_data_t* data)
 static void
 mmo_read_CObjIcons(mmo_data_t* data)
 {
+  Q_UNUSED(data);
 #ifdef MMO_DBG
   const char* sobj = "CObjIcons";
 #endif
@@ -756,7 +758,7 @@ mmo_read_CObjTrack(mmo_data_t* data)
 
 
 static void
-mmo_read_CObjText(mmo_data_t* data)
+mmo_read_CObjText(mmo_data_t*)
 {
 #ifdef MMO_DBG
   const char* sobj = "CObjText";
@@ -790,7 +792,7 @@ mmo_read_CObjText(mmo_data_t* data)
 
 
 static void
-mmo_read_CObjCurrentPosition(mmo_data_t* data)
+mmo_read_CObjCurrentPosition(mmo_data_t*)
 {
 #ifdef MMO_DBG
   const char* sobj = "CObjCurrentPosition";
@@ -1145,7 +1147,7 @@ mmo_writestr(const QString& str)
 
 
 static void
-mmo_enum_waypt_cb(const Waypoint* wpt)
+mmo_enum_waypt_cb(const Waypoint*)
 {
   mmo_obj_ct++;
 }
@@ -1521,6 +1523,8 @@ ff_vecs_t mmo_vecs = {
   NULL,
   mmo_args,
   CET_CHARSET_MS_ANSI, 0
+  , NULL_POS_OPS,
+  nullptr
 
 };
 
index a6c430c6a6cd270719330ce1064c441240bd8c87..a9fef6879cfe08d774474ecff3b23a21c3b8a855 100644 (file)
@@ -52,11 +52,11 @@ static char* opt_status;
 static char* opt_enable;
 
 arglist_t mtk_locus_args[] = {
-  {"baudrate", &opt_baudrate, "Speed in bits per second of serial port (autodetect=0)", "0", ARGTYPE_INT, ARG_NOMINMAX },
-  {"download", &opt_download, "Download logged fixes", "1", ARGTYPE_BOOL, ARG_NOMINMAX },
-  {"erase", &opt_erase, "Erase device data after download", "0", ARGTYPE_BOOL, ARG_NOMINMAX },
-  {"status", &opt_status, "Show device status", "0", ARGTYPE_BOOL, ARG_NOMINMAX },
-  {"enable", &opt_enable, "Enable logging after download", "0", ARGTYPE_BOOL, ARG_NOMINMAX },
+  {"baudrate", &opt_baudrate, "Speed in bits per second of serial port (autodetect=0)", "0", ARGTYPE_INT, ARG_NOMINMAX , nullptr},
+  {"download", &opt_download, "Download logged fixes", "1", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr },
+  {"erase", &opt_erase, "Erase device data after download", "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr },
+  {"status", &opt_status, "Show device status", "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr },
+  {"enable", &opt_enable, "Enable logging after download", "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr },
   ARG_TERMINATOR
 };
 
@@ -80,6 +80,8 @@ ff_vecs_t mtk_locus_vecs = {
   NULL, // exit
   mtk_locus_args,
   CET_CHARSET_ASCII, 0 /* ascii is the expected character set */
+  , NULL_POS_OPS,
+  nullptr
 };
 
 #define MYNAME "mtk_locus"
index 77fe328b10a9b1b7050dd6075baa3ae4430dc9ee..b46c0aaa173018eb1e50232bd4b780d41210dae3 100644 (file)
@@ -264,23 +264,23 @@ static int mtk_parse_info(const unsigned char* data, int dataLen);
 static arglist_t mtk_sargs[] = {
   {
     "erase", &OPT_erase, "Erase device data after download",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX
+    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "erase_only", &OPT_erase_only, "Only erase device data, do not download anything",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX
+    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "log_enable", &OPT_log_enable, "Enable logging after download",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX
+    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "csv",   &csv_file, "MTK compatible CSV output file",
-    NULL, ARGTYPE_STRING, ARG_NOMINMAX
+    NULL, ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   {
     "block_size_kb", &OPT_block_size_kb, "Size of blocks in KB to request from device",
-    "1", ARGTYPE_INT, "1", "64"
+    "1", ARGTYPE_INT, "1", "64", nullptr
   },
   ARG_TERMINATOR
 };
@@ -1696,6 +1696,8 @@ ff_vecs_t mtk_vecs = {
   mtk_sargs,
   CET_CHARSET_ASCII, 0                 /* ascii is the expected character set */
   /* not fixed, can be changed through command line parameter */
+  , NULL_POS_OPS,
+  nullptr
 };
 
 ff_vecs_t mtk_m241_vecs = {
@@ -1715,6 +1717,8 @@ ff_vecs_t mtk_m241_vecs = {
   mtk_sargs,
   CET_CHARSET_ASCII, 0                 /* ascii is the expected character set */
   /* not fixed, can be changed through command line parameter */
+  , NULL_POS_OPS,
+  nullptr
 };
 
 /* used for mtk-bin */
@@ -1722,7 +1726,7 @@ ff_vecs_t mtk_m241_vecs = {
 static arglist_t mtk_fargs[] = {
   {
     "csv",   &csv_file, "MTK compatible CSV output file",
-    NULL, ARGTYPE_STRING, ARG_NOMINMAX
+    NULL, ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   ARG_TERMINATOR
 };
@@ -1739,6 +1743,8 @@ ff_vecs_t mtk_fvecs = {
   NULL,
   mtk_fargs,
   CET_CHARSET_UTF8, 1         /* master process: don't convert anything | CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
 
 ff_vecs_t mtk_m241_fvecs = {
@@ -1753,6 +1759,8 @@ ff_vecs_t mtk_m241_fvecs = {
   NULL,
   mtk_fargs,
   CET_CHARSET_UTF8, 1         /* master process: don't convert anything | CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
 /* End file: mtk_logger.c */
 /**************************************************************************/
index 5ac119625d3573847ef61b8c00f78703ec464903..31313e20461c7adc6f258d6680dc88a8080546ef 100644 (file)
--- a/mynav.cc
+++ b/mynav.cc
@@ -167,4 +167,6 @@ ff_vecs_t mynav_vecs = {
   NULL,           //args
   CET_CHARSET_ASCII, 0  //encode,fixed_encode
   //NULL                //name dynamic/internal?
+  , NULL_POS_OPS,
+  nullptr
 };
index c40ad9722fb3c98a447a18d2d9fc7c28e5a8ac12..d8a298a9231d50467151c8366a9da629caa729b4 100644 (file)
@@ -28,7 +28,7 @@ static
 arglist_t nav_args[] = {
   {
     "noretired", &noretired, "Suppress retired geocaches",
-    NULL, ARGTYPE_BOOL, ARG_NOMINMAX
+    NULL, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   ARG_TERMINATOR
 };
@@ -178,7 +178,7 @@ NaviReadCache(const QXmlStreamReader& reader)
 }
 
 static void
-nav_read(void)
+nav_read()
 {
   QXmlStreamReader reader;
   gpsbabel::File file(read_fname);
@@ -203,23 +203,23 @@ nav_read(void)
 }
 
 static void
-nav_rd_deinit(void)
+nav_rd_deinit()
 {
 }
 
 static void
-nav_wr_init(const QString& fname)
+nav_wr_init(const QString&)
 {
   fatal(MYNAME ": Does not support writing Navicache files.\n");
 }
 
 static void
-nav_wr_deinit(void)
+nav_wr_deinit()
 {
 }
 
 static void
-nav_write(void)
+nav_write()
 {
 }
 
@@ -235,4 +235,6 @@ ff_vecs_t navicache_vecs = {
   NULL,
   nav_args,
   CET_CHARSET_UTF8, 0  /* CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
index 76f2c783f6f6ac0ac991ee26480394b7264be390..2a7c0a819dc1ccdc75138664241d32d1eca14b8c 100644 (file)
@@ -95,11 +95,11 @@ static
 arglist_t ng_args[] = {
   {
     "output", &process, "'wp' - Create waypoint file , 'rte' - Create route file",
-    "rte", ARGTYPE_STRING, ARG_NOMINMAX
+    "rte", ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   {
     "reorder", &reorder, "'n' - Keep the existing wp name, 'y' - rename waypoints",
-    "n", ARGTYPE_STRING, ARG_NOMINMAX
+    "n", ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
 
   ARG_TERMINATOR
@@ -423,4 +423,6 @@ ff_vecs_t ng_vecs = {
   NULL,
   ng_args,
   CET_CHARSET_HEBREW, 0
+  , NULL_POS_OPS,
+  nullptr
 };
index bdf884a2f7fda748e6a70dd4328a77b0c7ac3650..8dd51651e5bf517f95c353b616922d11fb07e36b 100644 (file)
@@ -140,27 +140,27 @@ static
 arglist_t navilink_args[] = {
   {
     "nuketrk", &nuketrk, "Delete all track points", NULL, ARGTYPE_BOOL,
-    ARG_NOMINMAX
+    ARG_NOMINMAX, nullptr
   },
   {
     "nukerte", &nukerte, "Delete all routes", NULL, ARGTYPE_BOOL,
-    ARG_NOMINMAX
+    ARG_NOMINMAX, nullptr
   },
   {
     "nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL,
-    ARG_NOMINMAX
+    ARG_NOMINMAX, nullptr
   },
   {
     "nukedlg", &nukedlg, "Clear the datalog", NULL, ARGTYPE_BOOL,
-    ARG_NOMINMAX
+    ARG_NOMINMAX, nullptr
   },
   {
     "datalog", &datalog, "Read from datalogger buffer",
-    NULL, ARGTYPE_BOOL, ARG_NOMINMAX
+    NULL, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   {
     "power_off", &poweroff, "Command unit to power itself down",
-    NULL, ARGTYPE_BOOL, ARG_NOMINMAX
+    NULL, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
   ARG_TERMINATOR
 };
@@ -622,7 +622,7 @@ serial_write_track(void)
 }
 
 static void
-serial_write_track_start(const route_head* track)
+serial_write_track_start(const route_head*)
 {
   track_data = (unsigned char*) xmalloc(MAX_WRITE_TRACKPOINTS * 32);
   track_data_ptr = track_data;
@@ -642,7 +642,7 @@ serial_write_track_point(const Waypoint* waypt)
 }
 
 static void
-serial_write_track_end(const route_head* track)
+serial_write_track_end(const route_head*)
 {
   if (track_data_ptr > track_data) {
     serial_write_track();
@@ -998,7 +998,7 @@ file_write_waypoint(const Waypoint* waypt)
 }
 
 static void
-file_write_track_start(const route_head* track)
+file_write_track_start(const route_head*)
 {
   track_serial = 1;
 }
@@ -1013,23 +1013,23 @@ file_write_track_point(const Waypoint* waypt)
 }
 
 static void
-file_write_track_end(const route_head* track)
+file_write_track_end(const route_head*)
 {
 }
 
 static void
-file_write_route_start(const route_head* track)
+file_write_route_start(const route_head*)
 {
   fatal(MYNAME ": Can't write routes to a file\n");
 }
 
 static void
-file_write_route_point(const Waypoint* waypt)
+file_write_route_point(const Waypoint*)
 {
 }
 
 static void
-file_write_route_end(const route_head* track)
+file_write_route_end(const route_head*)
 {
 }
 
@@ -1247,4 +1247,6 @@ ff_vecs_t navilink_vecs = {
   NULL,
   navilink_args,
   CET_CHARSET_ASCII, 0 /* CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
index 5626ef334e312f68dc4a3a15f289ea4e46e33a08..8ffb70f3a99b2d81f683a3e0492a2187ec146b81 100644 (file)
@@ -40,13 +40,13 @@ navitel_rd_init(const QString& fname)
 }
 
 static void
-navitel_rd_deinit(void)
+navitel_rd_deinit()
 {
   gbfclose(fin);
 }
 
 static void
-navitel_read_track(void)
+navitel_read_track()
 {
   int points, i;
   route_head* trk = NULL;
@@ -80,19 +80,19 @@ navitel_wr_init(const QString& fname)
 }
 
 static void
-navitel_wr_deinit(void)
+navitel_wr_deinit()
 {
   gbfclose(fout);
 }
 
 static void
-navitel_enum_trkpts(const Waypoint* wpt)
+navitel_enum_trkpts(const Waypoint*)
 {
   trkpts++;
 }
 
 static void
-navitel_disp_trk_head(const route_head* trk)
+navitel_disp_trk_head(const route_head*)
 {
   new_track = 1;
 }
@@ -115,7 +115,7 @@ navitel_disp_trkpts(const Waypoint* wpt)
 }
 
 static void
-navitel_write_track(void)
+navitel_write_track()
 {
   trkpts = 0;
   track_disp_all(NULL, NULL, navitel_enum_trkpts);
@@ -147,6 +147,8 @@ ff_vecs_t navitel_trk_vecs = {
   NULL,
   NULL,
   CET_CHARSET_UTF8, 1                  /* Nothing to convert */
+  , NULL_POS_OPS,
+  nullptr
 };
 
 /**************************************************************************/
index aef610ce507db250503b8fbff1000c441d79af33..03b4e6016576ab84761a837c2bf0ef1053798400 100644 (file)
@@ -43,23 +43,23 @@ static
 arglist_t netstumbler_args[] = {
   {
     "nseicon", &nseicon, "Non-stealth encrypted icon name",
-    "Red Square", ARGTYPE_STRING, ARG_NOMINMAX
+    "Red Square", ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   {
     "nsneicon", &nsneicon, "Non-stealth non-encrypted icon name",
-    "Green Square", ARGTYPE_STRING, ARG_NOMINMAX
+    "Green Square", ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   {
     "seicon", &seicon, "Stealth encrypted icon name",
-    "Red Diamond", ARGTYPE_STRING, ARG_NOMINMAX
+    "Red Diamond", ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   {
     "sneicon", &sneicon, "Stealth non-encrypted icon name",
-    "Green Diamond", ARGTYPE_STRING, ARG_NOMINMAX
+    "Green Diamond", ARGTYPE_STRING, ARG_NOMINMAX, nullptr
   },
   {
     "snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL,
-    ARG_NOMINMAX
+    ARG_NOMINMAX, nullptr
   },
   ARG_TERMINATOR
 };
@@ -346,4 +346,6 @@ ff_vecs_t netstumbler_vecs = {
   NULL,
   netstumbler_args,
   CET_CHARSET_ASCII, 0 /* CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
diff --git a/nmea.cc b/nmea.cc
index 6d8a98a10b5883344251433e2ee6267690f12161..d3c5a763abe772d0e0a0a1d9e53a3777ac785c21 100644 (file)
--- a/nmea.cc
+++ b/nmea.cc
@@ -198,22 +198,28 @@ static Waypoint* nmea_rd_posn(posn_status*);
 static void nmea_rd_posn_init(const QString& fname);
 
 arglist_t nmea_args[] = {
-  {"snlen", &snlenopt, "Max length of waypoint name to write", "6", ARGTYPE_INT, "1", "64" },
-  {"gprmc", &opt_gprmc, "Read/write GPRMC sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX },
-  {"gpgga", &opt_gpgga, "Read/write GPGGA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX },
-  {"gpvtg", &opt_gpvtg, "Read/write GPVTG sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX },
-  {"gpgsa", &opt_gpgsa, "Read/write GPGSA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX },
-  {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX },
+  #if 1
+  {"snlen", &snlenopt, "Max length of waypoint name to write", "6", ARGTYPE_INT, "1", "64", nullptr },
+  {"gprmc", &opt_gprmc, "Read/write GPRMC sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr },
+  {"gpgga", &opt_gpgga, "Read/write GPGGA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr },
+  {"gpvtg", &opt_gpvtg, "Read/write GPVTG sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr },
+  {"gpgsa", &opt_gpgsa, "Read/write GPGSA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr },
+  {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX , nullptr },
+  #endif
+  #if 0
   {
     "get_posn", &getposnarg, "Return current position as a waypoint",
-    NULL, ARGTYPE_BOOL, ARG_NOMINMAX
+    NULL, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   },
-  {"pause", &opt_sleep, "Decimal seconds to pause between groups of strings", NULL, ARGTYPE_INT, ARG_NOMINMAX },
-  {"append_positioning", &opt_append, "Append realtime positioning data to the output file instead of truncating", "0", ARGTYPE_BOOL, ARG_NOMINMAX },
-  {"baud", &opt_baud, "Speed in bits per second of serial port (baud=4800)", NULL, ARGTYPE_INT, ARG_NOMINMAX },
-  {"gisteq", &opt_gisteq, "Write tracks for Gisteq Phototracker", "0", ARGTYPE_BOOL, ARG_NOMINMAX },
-  {"ignore_fix", &opt_ignorefix, "Accept position fixes in gpgga marked invalid", "0", ARGTYPE_BOOL, ARG_NOMINMAX },
+  {"pause", &opt_sleep, "Decimal seconds to pause between groups of strings", NULL, ARGTYPE_INT, ARG_NOMINMAX , nullptr},
+  {"append_positioning", &opt_append, "Append realtime positioning data to the output file instead of truncating", "0", ARGTYPE_BOOL, ARG_NOMINMAX , nullptr},
+  {"baud", &opt_baud, "Speed in bits per second of serial port (baud=4800)", NULL, ARGTYPE_INT, ARG_NOMINMAX, nullptr },
+  {"gisteq", &opt_gisteq, "Write tracks for Gisteq Phototracker", "0", ARGTYPE_BOOL, ARG_NOMINMAX , nullptr},
+  #endif
+  #if 0
+  {"ignore_fix", &opt_ignorefix, "Accept position fixes in gpgga marked invalid", "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr},
   ARG_TERMINATOR
+  #endif
 };
 
 #define CHECK_BOOL(a) if (a && (*a == '0')) a = NULL
@@ -304,7 +310,7 @@ nmea_rd_init(const QString& fname)
 }
 
 static  void
-nmea_rd_deinit(void)
+nmea_rd_deinit()
 {
   switch (read_mode) {
   case rm_serial:
@@ -356,7 +362,7 @@ nmea_wr_init(const QString& portname)
 }
 
 static  void
-nmea_wr_deinit(void)
+nmea_wr_deinit()
 {
   gbfclose(file_out);
   mkshort_del_handle(&mkshort_handle);
@@ -1016,7 +1022,7 @@ nmea_parse_one_line(char* ibuf)
 }
 
 static void
-nmea_read(void)
+nmea_read()
 {
   char* ibuf;
   char* ck;
@@ -1130,7 +1136,7 @@ safe_print(int cnt, const char* b)
 static void reset_sirf_to_nmea(int br);
 
 static
-int hunt_sirf(void)
+int hunt_sirf()
 {
   /* Try to place the common BR's first to speed searching */
   static int br[] = {38400, 9600, 57600, 115200, 19200, 4800, -1};
@@ -1172,7 +1178,7 @@ int hunt_sirf(void)
 }
 
 static Waypoint*
-nmea_rd_posn(posn_status* posn_status)
+nmea_rd_posn(posn_status*)
 {
   char ibuf[1024];
   static double lt = -1;
@@ -1380,7 +1386,7 @@ nmea_trackpt_pr(const Waypoint* wpt)
 }
 
 static void
-nmea_write(void)
+nmea_write()
 {
   waypt_disp_all(nmea_wayptpr);
   track_disp_all(nmea_track_init, NULL, nmea_trackpt_pr);
@@ -1399,7 +1405,7 @@ nmea_wr_posn(Waypoint* wpt)
 }
 
 static void
-nmea_wr_posn_deinit(void)
+nmea_wr_posn_deinit()
 {
 // nmea_wr_deinit();
 }
diff --git a/nmea_.cc b/nmea_.cc
new file mode 100644 (file)
index 0000000..f1c2430
--- /dev/null
+++ b/nmea_.cc
@@ -0,0 +1,1492 @@
+/*
+       Read files containing selected NMEA 0183 sentences.
+       Based on information by Eino Uikkanenj
+
+       Copyright (C) 2004-2015 Robert Lipe, robertlipe+source@gpsbabel.org
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+
+#include "defs.h"
+#include "cet_util.h"
+#include "gbser.h"
+#include "strptime.h"
+#include "jeeps/gpsmath.h"
+
+#include <ctype.h>
+#include <math.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <QtCore/QStringList>
+
+/**********************************************************
+
+   ' 1      2      3        4 5         6 7 8  9   10   11 12  13 14 15
+   ' $GPGGA - Global Positioning System Fix Data
+   ' $GPGGA,155537,6006.718,N,02426.290,E,1,05,2.4,50.5,M,19.7,M,,*79
+   '  2    123519       Fix taken at 12:35:19 UTC
+   '  3,4  4807.038,N   Latitude 48 deg 07.038' N
+   '  5,6  01131.324,E  Longitude 11 deg 31.324' E
+   '  7    1            Fix quality: 0 = invalid
+   '                                 1 = GPS fix
+   '                                 2 = DGPS fix
+   '  8    08           Number of satellites being tracked
+   '  9    0.9          Horizontal dilution of position
+   ' 10,11 545.4,M      Altitude, Metres, above mean sea level
+   ' 12,13 46.9,M       Height of geoid (mean sea level) above WGS84 ellipsoid
+   ' 14    (empty field) time in seconds since last DGPS update
+   ' 15    (empty field) DGPS station ID number
+
+   ' $GPWPL - waypoint location
+   ' $GPWPL,4917.16,N,12310.64,W,003*65
+   '  2,3  4917.16,N    Latitude of waypoint
+   '  4,5  12310.64,W   Longitude of waypoint
+   '  6    003          Waypoint ID
+
+   ' $GPGLL - Geographic position, Latitude and Longitude
+   ' $GPGLL,4916.45,N,12311.12,W,225444,A
+   '  2,3  4916.46,N    Latitude 49 deg. 16.45 min. North
+   '  4,5  12311.12,W   Longitude 123 deg. 11.12 min. West
+   '  6    225444       Fix taken at 22:54:44 UTC
+   '  7    A            Data valid
+
+   ' $GPRMC - Recommended minimum specific GNSS Data
+   ' $GPRMC,085721.194,A,5917.7210,N,01103.9227,E,21.42,50.33,300504,,*07
+   '  2    085721       Fix taken at 08:57:21 UTC
+   '  3    A                           Fix valid (this field reads V if fix is not valid)
+   '  4,5  5917.7210,N   Latitude 59 deg 17.7210' N
+   '  6,7  01103.9227,E  Longitude 11 deg 03.9227' E
+   '  8    21.42                       Speed over ground (knots)
+   '  9    50.33                       Course over ground (true)
+   '   10   300504                     Date 30/05-2004
+   '  11   Empty field Magnetic variation
+
+         GSA - GPS DOP and active satellites
+         $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
+              A            Auto selection of 2D or 3D fix (M = manual)
+              3            3D fix
+              04,05...     PRNs of satellites used for fix (space for 12)
+              2.5          PDOP (dilution of precision)
+              1.3          Horizontal dilution of precision (HDOP)
+              2.1          Vertical dilution of precision (VDOP)
+                DOP is an indication of the effect of satellite geometry on
+                the accuracy of the fix.
+
+         VTG - Track made good and ground speed
+         $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K
+              054.7,T      True track made good
+              034.4,M      Magnetic track made good
+              005.5,N      Ground speed, knots
+              010.2,K      Ground speed, Kilometers per hour
+
+         WPL - waypoint location
+         $GPWPL,4917.16,N,12310.64,W,003*65
+              4917.16,N    Latitude of waypoint
+              12310.64,W   Longitude of waypoint
+              003          Waypoint ID
+                When a route is active, this sentence is sent once for each
+                waypoint in the route, in sequence. When all waypoints have
+                been reported, GPR00 is sent in the next data set. In any
+                group of sentences, only one WPL sentence, or an R00
+                sentence, will be sent.
+
+
+   ' The optional checksum field consists of a "*" and two hex digits repre-
+   ' senting the exclusive OR of all characters between, but not including,
+   ' the "$" and "*".  A checksum is required on some sentences.
+
+****************************************/
+
+/*
+ * An input file may have both GGA and GLL and RMC sentences for the exact
+ * same position fix. If we see a single GGA, start ignoring GLL's and RMC's.
+ *     GLL's will also be ignored if RMC's are found and GGA's not found.
+ */
+
+/*
+Zmarties notes:
+
+In practice, all fields of the NMEA sentences should be treated as optional -
+if the data is not available, then the field can be omitted (hence leading
+to the output of two consecutive commas).
+
+An NMEA recording can start anywhere in the stream of data.  It is therefore
+necessary to discard sentences until sufficient data has been processed to
+have all the necessary data to construct a waypoint.  In practice, this means
+discarding data until we have had the first sentence that provides the date.
+(We could scan forwards in the stream of data to find the first date, and
+then back apply it to all previous sentences, but that is probably more
+complexity that is necessary - the lost of one waypoint at the start of the
+stream can normally be tolerated.)
+
+If a sentence is received without a checksum, but previous sentences have
+had checksums, it is best to discard that sentence.  In practice, the only
+time I have seen this is when the recording stops suddenly, where the last
+sentence is truncated - and missing part of the line, including the checksum.
+*/
+
+typedef enum {
+  gp_unknown = 0,
+  gpgga,
+  gplgll,
+  gprmc
+} preferred_posn_type;
+
+static enum {
+  rm_unknown = 0,
+  rm_serial,
+  rm_file
+} read_mode;
+
+static gbfile* file_in, *file_out;
+static route_head* trk_head;
+static short_handle mkshort_handle;
+static preferred_posn_type posn_type;
+static struct tm tm;
+static Waypoint* curr_waypt;
+static Waypoint* last_waypt;
+static void* gbser_handle;
+static QString posn_fname;
+static queue pcmpt_head;
+
+static int without_date;       /* number of created trackpoints without a valid date */
+static struct tm opt_tm;       /* converted "date" parameter */
+
+#define MYNAME "nmea"
+
+static char* opt_gprmc;
+static char* opt_gpgga;
+static char* opt_gpvtg;
+static char* opt_gpgsa;
+static char* snlenopt;
+static char* optdate;
+static char* getposnarg;
+static char* opt_sleep;
+static char* opt_baud;
+static char* opt_append;
+static char* opt_gisteq;
+static char* opt_ignorefix;
+
+static long sleepus;
+static int getposn;
+static int append_output;
+static int amod_waypoint;
+
+static time_t last_time;
+static double last_read_time;   /* Last timestamp of GGA or PRMC */
+static int datum;
+static int had_checksum;
+
+static Waypoint* nmea_rd_posn(posn_status*);
+static void nmea_rd_posn_init(const QString& fname);
+
+arglist_t nmea_args[] = {
+  {"snlen", &snlenopt, "Max length of waypoint name to write", "6", ARGTYPE_INT, "1", "64" },
+  {"gprmc", &opt_gprmc, "Read/write GPRMC sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX },
+  {"gpgga", &opt_gpgga, "Read/write GPGGA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX },
+  {"gpvtg", &opt_gpvtg, "Read/write GPVTG sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX },
+  {"gpgsa", &opt_gpgsa, "Read/write GPGSA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX },
+  {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX },
+  {
+    "get_posn", &getposnarg, "Return current position as a waypoint",
+    NULL, ARGTYPE_BOOL, ARG_NOMINMAX
+  },
+  {"pause", &opt_sleep, "Decimal seconds to pause between groups of strings", NULL, ARGTYPE_INT, ARG_NOMINMAX },
+  {"append_positioning", &opt_append, "Append realtime positioning data to the output file instead of truncating", "0", ARGTYPE_BOOL, ARG_NOMINMAX },
+  {"baud", &opt_baud, "Speed in bits per second of serial port (baud=4800)", NULL, ARGTYPE_INT, ARG_NOMINMAX },
+  {"gisteq", &opt_gisteq, "Write tracks for Gisteq Phototracker", "0", ARGTYPE_BOOL, ARG_NOMINMAX },
+  {"ignore_fix", &opt_ignorefix, "Accept position fixes in gpgga marked invalid", "0", ARGTYPE_BOOL, ARG_NOMINMAX },
+  ARG_TERMINATOR
+};
+
+#define CHECK_BOOL(a) if (a && (*a == '0')) a = NULL
+
+/*
+ * Slightly different than the Magellan checksum fn.
+ */
+int
+nmea_cksum(const char* const buf)
+{
+  int x = 0 ;
+  const char* p;
+
+  for (p = buf; *p; p++) {
+    x ^= *p;
+  }
+  return x;
+}
+
+static void
+nmea_add_wpt(Waypoint* wpt, route_head* trk)
+{
+  if (datum != DATUM_WGS84) {
+    double lat, lon, alt;
+    GPS_Math_Known_Datum_To_WGS84_M(
+      wpt->latitude, wpt->longitude, 0,
+      &lat, &lon, &alt, datum);
+    wpt->latitude = lat;
+    wpt->longitude = lon;
+  }
+  if (trk != NULL) {
+    track_add_wpt(trk, wpt);
+  } else {
+    waypt_add(wpt);
+  }
+}
+
+static void
+nmea_release_wpt(Waypoint* wpt)
+{
+  if (wpt && ((wpt->Q.next == NULL) || (wpt->Q.next == &wpt->Q))) {
+    /* This waypoint isn't queued.
+       Release it, because we don't have any reference to this
+       waypoint (! memory leak !) */
+    delete wpt;
+  }
+}
+
+static void
+nmea_rd_init(const QString& fname)
+{
+  curr_waypt = NULL;
+  last_waypt = NULL;
+  last_time = -1;
+  datum = DATUM_WGS84;
+  had_checksum = 0;
+
+  CHECK_BOOL(opt_gprmc);
+  CHECK_BOOL(opt_gpgga);
+  CHECK_BOOL(opt_gpvtg);
+  CHECK_BOOL(opt_gpgsa);
+  CHECK_BOOL(opt_gisteq);
+
+  QUEUE_INIT(&pcmpt_head);
+
+  if (getposnarg) {
+    getposn = 1;
+  }
+
+  /* A special case hack that gets our current position and returns
+   * it as one waypoint.
+   */
+  if (getposn) {
+    Waypoint* wpt;
+    posn_status st;
+    nmea_rd_posn_init(fname);
+    wpt = nmea_rd_posn(&st);
+    if (!wpt) {
+      return;
+    }
+    wpt->shortname = "Position";
+    nmea_add_wpt(wpt, NULL);
+    return;
+  }
+
+  read_mode = rm_file;
+  file_in = gbfopen(fname, "rb", MYNAME);
+}
+
+static  void
+nmea_rd_deinit(void)
+{
+  switch (read_mode) {
+  case rm_serial:
+    gbser_deinit(gbser_handle);
+    break;
+  case rm_file:
+    gbfclose(file_in);
+    file_in = NULL;
+    break;
+  default:
+    fatal("nmea_rd_deinit: illegal read_mode.\n");
+    break;
+  }
+
+  posn_fname.clear();
+
+}
+
+static void
+nmea_wr_init(const QString& portname)
+{
+  CHECK_BOOL(opt_gprmc);
+  CHECK_BOOL(opt_gpgga);
+  CHECK_BOOL(opt_gpvtg);
+  CHECK_BOOL(opt_gpgsa);
+  CHECK_BOOL(opt_gisteq);
+
+  append_output = atoi(opt_append);
+
+  file_out = gbfopen(portname, append_output ? "a+" : "w+", MYNAME);
+
+  sleepus = -1;
+  if (opt_sleep) {
+    if (*opt_sleep) {
+      sleepus = 1e6 * atof(opt_sleep);
+    } else {
+      sleepus = -1;
+    }
+  }
+
+  mkshort_handle = mkshort_new_handle();
+  setshort_length(mkshort_handle, atoi(snlenopt));
+
+  if (opt_gisteq) {
+    opt_gpgga = NULL;
+    opt_gpvtg = NULL;
+    opt_gpgsa = NULL;
+  }
+}
+
+static  void
+nmea_wr_deinit(void)
+{
+  gbfclose(file_out);
+  mkshort_del_handle(&mkshort_handle);
+}
+
+static void
+nmea_set_waypoint_time(Waypoint* wpt, struct tm* time, double fsec)
+{
+  if (time->tm_year == 0) {
+    wpt->SetCreationTime(((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec, lround(1000.0 * fsec));
+    if (wpt->wpt_flags.fmt_use == 0) {
+      wpt->wpt_flags.fmt_use = 1;
+      without_date++;
+    }
+  } else {
+    wpt->SetCreationTime(mkgmtime(time), lround(1000.0 * fsec));
+    if (wpt->wpt_flags.fmt_use != 0) {
+      wpt->wpt_flags.fmt_use = 0;
+      without_date--;
+    }
+  }
+}
+
+static void
+gpgll_parse(char* ibuf)
+{
+  if (trk_head == NULL) {
+    trk_head = route_head_alloc();
+    track_add_head(trk_head);
+  }
+
+  QStringList fields = QString(ibuf).split(",", QString::KeepEmptyParts);
+
+  double latdeg = 0;
+  if (fields.size() > 1) latdeg = fields[1].toDouble();
+  QChar latdir = 'N';
+  if (fields.size() > 2) latdir = fields[2][0];
+  double lngdeg = 0;
+  if (fields.size() > 3) lngdeg = fields[3].toDouble();
+  QChar lngdir = 'E';
+  if (fields.size() > 4) lngdir = fields[4][0];
+  double hmsd = 0;
+  if (fields.size() > 5) hmsd = fields[5].toDouble();
+  bool valid = false;
+  if (fields.size() > 6) valid = fields[6].startsWith('A');
+
+  if (!valid) {
+    return;
+  }
+
+  int hms = (int) hmsd;
+  last_read_time = hms;
+  double fsec = hmsd - hms;
+
+  tm.tm_sec = hms % 100;
+  hms = hms / 100;
+  tm.tm_min = hms % 100;
+  hms = hms / 100;
+  tm.tm_hour = hms % 100;
+
+  Waypoint* waypt = new Waypoint;
+
+  nmea_set_waypoint_time(waypt, &tm, fsec);
+
+  if (latdir == 'S') {
+    latdeg = -latdeg;
+  }
+  waypt->latitude = ddmm2degrees(latdeg);
+
+  if (lngdir == 'W') {
+    lngdeg = -lngdeg;
+  }
+  waypt->longitude = ddmm2degrees(lngdeg);
+
+  nmea_release_wpt(curr_waypt);
+  curr_waypt = waypt;
+}
+
+static void
+gpgga_parse(char* ibuf)
+{
+  if (trk_head == NULL) {
+    trk_head = route_head_alloc();
+    track_add_head(trk_head);
+  }
+
+  QStringList fields = QString(ibuf).split(",", QString::KeepEmptyParts);
+  double hms = 0;
+  if (fields.size() > 1) hms = fields[1].toDouble();
+  double latdeg = 0;
+  if (fields.size() > 2) latdeg = fields[2].toDouble();
+  QChar latdir = 'N';
+  if (fields.size() > 3) latdir = fields[3][0];
+  double lngdeg = 0;
+  if (fields.size() > 4) lngdeg = fields[4].toDouble();
+  QChar lngdir = 'W';
+  if (fields.size() > 5) lngdir = fields[5][0];
+  int fix = fix_unknown;
+  if (fields.size() > 6) fix = fields[6].toInt();
+  int nsats = 0;
+  if (fields.size() > 7) nsats = fields[7].toInt();
+  double hdop = 0;
+  if (fields.size() > 8) hdop = fields[8].toDouble();
+  double alt = unknown_alt;
+  if (fields.size() > 9) alt = fields[9].toDouble();
+  QChar altunits;
+  if (fields.size() > 10) altunits = fields[10][0];
+  double geoidheight = unknown_alt;
+  if (fields.size() > 11) geoidheight = fields[11].toDouble();
+  QChar geoidheightunits = 'M';
+  if (fields.size() > 12) geoidheightunits = fields[12][0];
+
+  /*
+   * In serial mode, allow the fix with an invalid position through
+   * as serial units will often spit a remembered position up and
+   * that is more comfortable than nothing at all...
+   */
+  CHECK_BOOL(opt_ignorefix);
+  if ((fix <= 0) && (read_mode != rm_serial) && (!opt_ignorefix)) {
+    return;
+  }
+
+  last_read_time = hms;
+  double fsec = hms - (int)hms;
+
+  tm.tm_sec = (long) hms % 100;
+  hms = hms / 100;
+  tm.tm_min = (long) hms % 100;
+  hms = hms / 100;
+  tm.tm_hour = (long) hms % 100;
+
+  Waypoint* waypt = new Waypoint;
+
+  nmea_set_waypoint_time(waypt, &tm, fsec);
+
+  if (latdir == 'S') {
+    latdeg = -latdeg;
+  }
+  waypt->latitude = ddmm2degrees(latdeg);
+
+  if (lngdir == 'W') {
+    lngdeg = -lngdeg;
+  }
+  waypt->longitude = ddmm2degrees(lngdeg);
+
+  waypt->altitude = alt;
+
+  WAYPT_SET(waypt, geoidheight, geoidheight);
+
+  waypt->sat   = nsats;
+
+  waypt->hdop  = hdop;
+
+  switch (fix) {
+  case 0:
+    waypt->fix = fix_none;
+    break;
+  case 1:
+    waypt->fix  = (nsats>3)?(fix_3d):(fix_2d);
+    break;
+  case 2:
+    waypt->fix = fix_dgps;
+    break;
+  case 3:
+    waypt->fix = fix_pps;
+    break;
+  }
+
+  nmea_release_wpt(curr_waypt);
+  curr_waypt = waypt;
+}
+
+static void
+gprmc_parse(char* ibuf)
+{
+  if (trk_head == NULL) {
+    trk_head = route_head_alloc();
+    track_add_head(trk_head);
+  }
+
+  QStringList fields = QString(ibuf).split(",", QString::KeepEmptyParts);
+  double hms = 0;
+  if (fields.size() > 1) hms = fields[1].toDouble();
+  QChar fix = 'V'; // V == "Invalid"
+  if (fields.size() > 2) fix = fields[2][0];
+  double latdeg = 0;
+  if (fields.size() > 3) latdeg = fields[3].toDouble();
+  QChar latdir = 'N';
+  if (fields.size() > 4) latdir = fields[4][0];
+  double lngdeg = 0;
+  if (fields.size() > 5) lngdeg = fields[5].toDouble();
+  QChar lngdir = 'W';
+  if (fields.size() > 6) lngdir = fields[6][0];
+  double speed = 0;
+  if (fields.size() > 7) speed = fields[7].toDouble();
+  double course = 0;
+  if (fields.size() > 8) course = fields[8].toDouble();
+  int dmy = 0;
+  if (fields.size() > 9) dmy = fields[9].toDouble();
+
+  if (fix != 'A') {
+    /* ignore this fix - it is invalid */
+    return;
+  }
+
+  last_read_time = hms;
+  double fsec = hms - (int)hms;
+
+  tm.tm_sec = (long) hms % 100;
+  hms = hms / 100;
+  tm.tm_min = (long) hms % 100;
+  hms = hms / 100;
+  tm.tm_hour = (long) hms % 100;
+
+  tm.tm_year = dmy % 100 + 100;
+  dmy = dmy / 100;
+  tm.tm_mon  = dmy % 100 - 1;
+  dmy = dmy / 100;
+  tm.tm_mday = dmy;
+
+  if (posn_type == gpgga) {
+    /* capture useful data update and exit */
+    if (curr_waypt) {
+      if (! WAYPT_HAS(curr_waypt, speed)) {
+        WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed));
+      }
+      if (! WAYPT_HAS(curr_waypt, course)) {
+        WAYPT_SET(curr_waypt, course, course);
+      }
+      /* The change of date wasn't recorded when
+       * going from 235959 to 000000. */
+      nmea_set_waypoint_time(curr_waypt, &tm, fsec);
+    }
+    /* This point is both a waypoint and a trackpoint. */
+    if (amod_waypoint) {
+      waypt_add(new Waypoint(*curr_waypt));
+      amod_waypoint = 0;
+    }
+    return;
+  }
+
+  Waypoint* waypt = new Waypoint;
+
+  WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed));
+  WAYPT_SET(waypt, course, course);
+
+  nmea_set_waypoint_time(waypt, &tm, fsec);
+
+  if (latdir == 'S') {
+    latdeg = -latdeg;
+  }
+  waypt->latitude = ddmm2degrees(latdeg);
+
+  if (lngdir == 'W') {
+    lngdeg = -lngdeg;
+  }
+  waypt->longitude = ddmm2degrees(lngdeg);
+
+  nmea_release_wpt(curr_waypt);
+  curr_waypt = waypt;
+
+  /* This point is both a waypoint and a trackpoint. */
+  if (amod_waypoint) {
+    waypt_add(new Waypoint(*waypt));
+    amod_waypoint = 0;
+  }
+}
+
+static void
+gpwpl_parse(char* ibuf)
+{
+  // The last field isn't actually separated by a field separator and
+  // is a string, so we brutally whack the checksum (trailing *NN).
+  QString qibuf = QString(ibuf);
+  qibuf.truncate(qibuf.lastIndexOf('*'));
+  QStringList fields = qibuf.split(",", QString::KeepEmptyParts);
+
+  double latdeg = 0;
+  if (fields.size() > 1) latdeg = fields[1].toDouble();
+  QChar latdir = 'N';
+  if (fields.size() > 2) latdir = fields[2][0];
+  double lngdeg = 0;
+  if (fields.size() > 3) lngdeg = fields[3].toDouble();
+  QChar lngdir = 'E';
+  if (fields.size() > 4) lngdir = fields[4][0];
+  QString sname;
+  if (fields.size() > 5) sname = fields[5];
+
+  if (latdir == 'S') {
+    latdeg = -latdeg;
+  }
+  if (lngdir == 'W') {
+    lngdeg = -lngdeg;
+  }
+
+  Waypoint* waypt = new Waypoint;
+  waypt->latitude = ddmm2degrees(latdeg);
+  waypt->longitude = ddmm2degrees(lngdeg);
+  waypt->shortname = sname;
+
+  curr_waypt = NULL; /* waypoints won't be updated with GPS fixes */
+  nmea_add_wpt(waypt, NULL);
+}
+
+static void
+gpzda_parse(char* ibuf)
+{
+  double hms;
+  int dd, mm, yy, lclhrs, lclmins;
+
+  sscanf(ibuf,"$%*2cZDA,%lf,%d,%d,%d,%d,%d",
+         &hms, &dd, &mm, &yy, &lclhrs, &lclmins);
+  tm.tm_sec  = (int) hms % 100;
+  tm.tm_min  = (((int) hms - tm.tm_sec) / 100) % 100;
+  tm.tm_hour = (int) hms / 10000;
+  tm.tm_mday = dd;
+  tm.tm_mon  = mm - 1;
+  tm.tm_year = yy - 1900;
+  // FIXME: why do we do all this and then do nothing with the result?
+  // This can't have worked.
+}
+
+static void
+gpgsa_parse(char* ibuf)
+{
+  char fixauto;
+  char fix;
+  int  prn[12] = {0};
+  int  scn,cnt;
+  float pdop=0,hdop=0,vdop=0;
+  char*        tok=0;
+
+  memset(prn,0xff,sizeof(prn));
+#if 0
+  scn = sscanf(ibuf,"$%*2cGSA,%c,%c,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
+               &fixauto, &fix,
+               &prn[0],&prn[1],&prn[2],&prn[3],&prn[4],&prn[5],
+               &prn[6],&prn[7],&prn[8],&prn[9],&prn[10],&prn[11]);
+  if (scn < 2) {
+    warning(MYNAME ": Short GSA sentence.\n");
+  }
+  /*
+       sscanf has scanned all the leftmost elements
+       we'll rescan by skipping 15 commas to the dops
+  */
+  tok = ibuf;
+  for (cnt=0; (tok)&&(cnt<15); cnt++) {
+    tok = strchr(tok,',');
+    if (!tok) {
+      break;
+    }
+    tok++;
+  }
+  if (tok) {
+    sscanf(tok,"%f,%f,%f",&pdop,&hdop,&vdop);
+  }
+#else
+  QStringList fields = QString(ibuf).split(",", QString::KeepEmptyParts);
+  if (fields.size() > 1)
+    if (fields[1] == 3) {
+      curr_waypt->fix = fix_3d;
+    } else {
+      curr_waypt->fix = fix_2d;
+    }
+    curr_waypt->pdop = pdop;
+    curr_waypt->hdop = hdop;
+    curr_waypt->vdop = vdop;
+#endif
+#if 0
+  if (curr_waypt) {
+
+    if (curr_waypt->fix!=fix_dgps) {
+      if       (fix=='3')      {
+        curr_waypt->fix=fix_3d;
+      } else if (fix=='2')     {
+        curr_waypt->fix=fix_2d;
+      }
+    }
+
+    curr_waypt->pdop = pdop;
+    curr_waypt->hdop = hdop;
+    curr_waypt->vdop = vdop;
+
+    if (curr_waypt->sat  <= 0) {
+      for (cnt=0; cnt<12; cnt++) {
+        curr_waypt->sat += (prn[cnt]>0)?(1):(0);
+      }
+    }
+  }
+#endif
+}
+
+static void
+gpvtg_parse(char* ibuf)
+{
+  QStringList fields = QString(ibuf).split(",", QString::KeepEmptyParts);
+  double course = 0;
+  if (fields.size() > 1) course = fields[1].toDouble();
+  double speed_n = 0;
+  if (fields.size() > 5) speed_n = fields[5].toDouble();
+  double speed_k = 0;
+  if (fields.size() > 7) speed_k = fields[7].toDouble();
+
+  if (curr_waypt) {
+    WAYPT_SET(curr_waypt, course, course);
+    if (speed_k > 0) {
+      WAYPT_SET(curr_waypt, speed, KPH_TO_MPS(speed_k))
+    } else {
+      WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed_n));
+    }
+  }
+
+}
+
+/*
+ *  AVMAP EKP-IV Tracks - a proprietary (and very weird) extended NMEA.
+ * https://sourceforge.net/tracker/?func=detail&atid=489478&aid=1640814&group_id=58972
+ */
+static
+double pcmpt_deg(int d)
+{
+  int deg = d  / 100000;
+  double minutes = (((d / 100000.0) - deg) * 100) / 60.0;
+  return (double) deg + minutes;
+}
+
+void
+pcmpt_parse(char* ibuf)
+{
+  int i, j1, j2, j3, j4, j5, j6;
+  int lat, lon;
+  char altflag, u1, u2;
+  float alt, f1, f2;
+  char coords[20] = {0};
+  int dmy, hms;
+
+  dmy = hms = 0;
+
+  sscanf(ibuf,"$PCMPT,%d,%d,%d,%c,%f,%d,%19[^,],%d,%f,%d,%f,%c,%d,%c,%d",
+         &j1, &j2, &j3, &altflag, &alt, &j4, (char*) &coords,
+         &j5, &f1, &j6, &f2, &u1, &dmy, &u2, &hms);
+
+  if (altflag == 'D' && curr_waypt && alt > 0) {
+    curr_waypt->altitude =  alt /*+ 500*/;
+    return;
+  }
+
+  /*
+   * There are a couple of different second line records, but we
+   * don't care about them.
+   */
+  if (j2 != 1) {
+    return;
+  }
+
+  sscanf(coords, "%d%n", &lat, &i);
+  if (coords[i] == 'S') {
+    lat = -lat;
+  }
+  sscanf(coords + i + 1, "%d%n", &lon, &i);
+  if (coords[i] == 'W') {
+    lon= -lon;
+  }
+
+  if (lat || lon) {
+    curr_waypt = new Waypoint;
+    curr_waypt->longitude = pcmpt_deg(lon);
+    curr_waypt->latitude = pcmpt_deg(lat);
+
+    tm.tm_sec = (long) hms % 100;
+    hms = hms / 100;
+    tm.tm_min = (long) hms % 100;
+    hms = hms / 100;
+    tm.tm_hour = (long) hms % 100;
+
+    tm.tm_year = dmy % 10000 - 1900;
+    dmy = dmy / 10000;
+    tm.tm_mon  = dmy % 100 - 1;
+    dmy = dmy / 100;
+    tm.tm_mday = dmy;
+    nmea_set_waypoint_time(curr_waypt, &tm, 0);
+    ENQUEUE_HEAD(&pcmpt_head, &curr_waypt->Q);
+  } else {
+    queue* elem, *tmp;
+    route_head* trk_head;
+
+    if (QUEUE_EMPTY(&pcmpt_head)) {
+      return;
+    }
+
+    /*
+     * Since we oh-so-cleverly inserted points at the head,
+     * we can rip through the queue forward now to get our
+    `           * handy-dandy reversing effect.
+     */
+    trk_head = route_head_alloc();
+    track_add_head(trk_head);
+    QUEUE_FOR_EACH(&pcmpt_head, elem, tmp) {
+      Waypoint* wpt = (Waypoint*) dequeue(elem);
+      nmea_add_wpt(wpt, trk_head);
+    }
+  }
+}
+
+static void
+nmea_fix_timestamps(route_head* track)
+{
+  if ((trk_head == NULL) || (without_date == 0)) {
+    return;
+  }
+
+  if (tm.tm_year == 0) {
+    queue* elem, *temp;
+    Waypoint* prev = NULL;
+    time_t delta_tm;
+
+    if (optdate == NULL) {
+      warning(MYNAME ": No date found within track (all points dropped)!\n");
+      warning(MYNAME ": Please use option \"date\" to preset a valid date for thoose tracks.\n");
+      track_del_head(track);
+      return;
+    }
+    delta_tm = mkgmtime(&opt_tm);
+
+    QUEUE_FOR_EACH(&track->waypoint_list, elem, temp) {
+      Waypoint* wpt = (Waypoint*)elem;
+
+      wpt->creation_time += delta_tm;
+      if ((prev != NULL) && (prev->creation_time > wpt->creation_time)) {      /* go over midnight ? */
+        delta_tm += SECONDS_PER_DAY;
+        wpt->creation_time += SECONDS_PER_DAY;
+      }
+      prev = wpt;
+    }
+  } else {
+    time_t prev;
+    queue* elem;
+
+    tm.tm_hour = 23;   /* last date found */
+    tm.tm_min = 59;
+    tm.tm_sec = 59;
+
+    prev = mkgmtime(&tm);
+
+    /* go backward through the track and complete timestamps */
+
+    for (elem = QUEUE_LAST(&track->waypoint_list); elem != &track->waypoint_list; elem=elem->prev) {
+      Waypoint* wpt = (Waypoint*)elem;
+
+      if (wpt->wpt_flags.fmt_use != 0) {
+        time_t dt;
+
+        wpt->wpt_flags.fmt_use = 0;    /* reset flag */
+
+        dt = (prev / SECONDS_PER_DAY) * SECONDS_PER_DAY;
+        wpt->creation_time += dt;
+        if (wpt->creation_time.toTime_t() > prev) {
+          wpt->creation_time+=SECONDS_PER_DAY;
+        }
+      }
+      prev = wpt->GetCreationTime().toTime_t();
+    }
+  }
+}
+
+static int
+notalkerid_strmatch(const char * s1, const char *sentenceFormatterMnemonicCode)
+{
+/*
+ * compare leading start of parametric sentence character ('$'), sentence address field, and trailing comma
+ * to the desired sentence formatter mneumonic code (the 3rd-5th characters of the sentence address field).
+ * The talker identifier mneumonic (the 1st-2nd characters of the sentence address field)
+ * is likely "GP" for Global Posilioning System (GPS)
+ * but other talkers like "IN" for Integrated Navigation can emit relevant sentences,
+ * so we ignore the talker identifier mneumonic.
+ */
+return strncmp(s1,"$",1) || strncmp(s1+3,sentenceFormatterMnemonicCode,3) || strncmp(s1+6,",",1);
+}
+
+void
+nmea_parse_one_line(char* ibuf)
+{
+  char* ck;
+  int ckval, ckcmp;
+  char* tbuf = lrtrim(ibuf);
+
+  /*
+   * GISTEQ PhotoTracker (stupidly) puts a bogus field in front
+   * of the line.  Look for it and toss it.
+   */
+  if (0 == strncmp(tbuf, "---,", 4)) {
+    tbuf += 4;
+  }
+
+  if (*tbuf != '$') {
+    return;
+  }
+
+  ck = strrchr(tbuf, '*');
+  if (ck != NULL) {
+    *ck = '\0';
+    ckval = nmea_cksum(&tbuf[1]);
+    *ck = '*';
+    ck++;
+    sscanf(ck, "%2X", &ckcmp);
+    if (ckval != ckcmp) {
+#if 0
+      printf("ckval %X, %X, %s\n", ckval, ckcmp, ck);
+      printf("NMEA %s\n", tbuf);
+#endif
+      return;
+    }
+
+    had_checksum = 1;
+  } else if (had_checksum) {
+    /* we have had a checksum on all previous sentences, but not on this
+    one, which probably indicates this line is truncated */
+    had_checksum = 0;
+    return;
+  }
+
+  if (strstr(tbuf+1,"$")!=NULL) {
+    /* If line has more than one $, there is probably an error in it. */
+    return;
+  }
+
+  /* @@@ zmarties: The parse routines all assume all fields are present, but
+     the NMEA format allows any field to be missed out if there is no data
+     for that field.  Rather than change all the parse routines, we first
+     substitute a default value of zero for any missing field.
+  */
+  if (strstr(tbuf, ",,")) {
+    tbuf = gstrsub(tbuf, ",,", ",0,");
+  }
+
+  if (0 == notalkerid_strmatch(tbuf, "WPL")) {
+    gpwpl_parse(tbuf);
+  } else if (opt_gpgga && (0 == notalkerid_strmatch(tbuf, "GGA"))) {
+    posn_type = gpgga;
+    gpgga_parse(tbuf);
+  } else if (opt_gprmc && (0 == notalkerid_strmatch(tbuf, "RMC"))) {
+    if (posn_type != gpgga) {
+      posn_type = gprmc;
+    }
+    /*
+     * Always call gprmc_parse() because like GPZDA
+     * it contains the full date.
+     */
+    gprmc_parse(tbuf);
+  } else if (0 == notalkerid_strmatch(tbuf, "GLL")) {
+    if ((posn_type != gpgga) && (posn_type != gprmc)) {
+      gpgll_parse(tbuf);
+    }
+  } else if (0 == notalkerid_strmatch(tbuf, "ZDA")) {
+    gpzda_parse(tbuf);
+  } else if (0 == strncmp(tbuf, "$PCMPT,", 7)) {
+    pcmpt_parse(tbuf);
+  } else if (opt_gpvtg && (0 == notalkerid_strmatch(tbuf, "VTG"))) {
+    gpvtg_parse(tbuf); /* speed and course */
+  } else if (opt_gpgsa && (0 == notalkerid_strmatch(tbuf, "GSA"))) {
+    gpgsa_parse(tbuf); /* GPS fix */
+  } else if (0 == strncmp(tbuf, "$ADPMB,5,0", 10)) {
+    amod_waypoint = 1;
+  }
+
+  if (tbuf != ibuf) {
+    /* clear up the dynamic buffer we used because substition was required */
+    xfree(tbuf);
+  }
+}
+
+static void
+nmea_read(void)
+{
+  char* ibuf;
+  char* ck;
+  double lt = -1;
+  int line = -1;
+
+  posn_type = gp_unknown;
+  trk_head = NULL;
+  without_date = 0;
+  memset(&tm, 0, sizeof(tm));
+  opt_tm = tm;
+
+  /* This was done in rd_init() */
+  if (getposn) {
+    return;
+  }
+
+  if (optdate) {
+    memset(&opt_tm, 0, sizeof(opt_tm));
+
+    ck = (char*)strptime(optdate, "%Y%m%d", &opt_tm);
+    if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) {
+      fatal(MYNAME ": Invalid date \"%s\"!\n", optdate);
+    } else if (opt_tm.tm_year < 70) {
+      fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate);
+    }
+  }
+
+  curr_waypt = NULL;
+
+  while ((ibuf = gbfgetstr(file_in))) {
+    char* sdatum, *cx;
+
+    line++;
+
+    if ((line == 0) & file_in->unicode) {
+      cet_convert_init(CET_CHARSET_UTF8, 1);
+    }
+
+    if ((line == 0) && (case_ignore_strncmp(ibuf, "@SonyGPS/ver", 12) == 0)) {
+      /* special hack for Sony GPS-CS1 files:
+         they are fully (?) nmea compatible, but come with a header line like
+         "@Sonygps/ver1.0/wgs-84". */
+      /* The Sony GPS-CS3KA extends that line even further
+         so we now look for the second field to be /
+         delimited.
+         @Sonygps/ver1.0/wgs-84/gps-cs3.0
+       */
+
+      /* Check the GPS datum */
+      cx = strchr(&ibuf[12], '/');
+      if (cx != NULL) {
+        char* edatum;
+        sdatum = cx + 1;
+        edatum = strchr(sdatum, '/');
+        if (edatum) {
+          *edatum = 0;
+        }
+        datum = GPS_Lookup_Datum_Index(sdatum);
+        if (datum < 0) {
+          fatal(MYNAME "/SonyGPS: Unsupported datum \"%s\" in source data!\n", sdatum);
+        }
+      }
+      continue;
+    }
+
+    nmea_parse_one_line(ibuf);
+    if (lt != last_read_time && curr_waypt && trk_head) {
+      if (curr_waypt != last_waypt) {
+        nmea_add_wpt(curr_waypt, trk_head);
+        last_waypt = curr_waypt;
+      }
+      lt = last_read_time;
+    }
+  }
+
+  /* try to complete date-less trackpoints */
+  nmea_fix_timestamps(trk_head);
+}
+
+void
+nmea_rd_posn_init(const QString& fname)
+{
+  if ((gbser_handle = gbser_init(qPrintable(fname))) != NULL) {
+    read_mode = rm_serial;
+    gbser_set_speed(gbser_handle, 4800);
+  } else {
+    fatal(MYNAME ": Could not open '%s' for position tracking.\n", qPrintable(fname));
+  }
+
+  gbser_flush(gbser_handle);
+
+  if (opt_baud) {
+    if (!gbser_set_speed(gbser_handle, atoi(opt_baud))) {
+      fatal(MYNAME ": Unable to set baud rate %s\n", opt_baud);
+    }
+  }
+  posn_fname = fname;
+}
+
+static void
+safe_print(int cnt, const char* b)
+{
+  int i;
+  for (i = 0; i < cnt; i++) {
+    char c = isprint(b[i]) ? b[i] : '.';
+    fputc(c, stderr);
+  }
+}
+
+static void reset_sirf_to_nmea(int br);
+
+static
+int hunt_sirf(void)
+{
+  /* Try to place the common BR's first to speed searching */
+  static int br[] = {38400, 9600, 57600, 115200, 19200, 4800, -1};
+  static int* brp = &br[0];
+  char ibuf[1024];
+
+  for (brp = br; *brp > 0; brp++) {
+    int rv;
+    if (global_opts.debug_level > 1) {
+      fprintf(stderr, "Trying %d\n", *brp);
+    }
+
+    /*
+     * Cycle our port's data speed and spray the "change to NMEA
+     * mode to the device.
+     */
+    gbser_set_speed(gbser_handle, *brp);
+    reset_sirf_to_nmea(*brp);
+
+    rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf),
+                         1000, 0x0a, 0x0d);
+    /*
+     * If we didn't get a read error but did get a string that
+     * started with a dollar sign, we're probably in NMEA mode
+     * now.
+     */
+    if ((rv > -1) && (strlen(ibuf) > 0) && ibuf[0] == '$') {
+      return 1;
+    }
+
+    /*
+     * If nothing was received, it's not a sirf part.  Fast exit.
+     */
+    if (rv < 0) {
+      return 0;
+    }
+  }
+  return 0;
+}
+
+static Waypoint*
+nmea_rd_posn(posn_status* posn_status)
+{
+  char ibuf[1024];
+  static double lt = -1;
+  int i;
+  int am_sirf = 0;
+
+  /*
+   * Read a handful of sentences, collecting the best info we
+   * can.  If the timestamp changes (indicating the sequence is
+   * about to restart and thus the one we're collecting isn't going
+   * to get any better than we now have) hand that back to the caller.
+   */
+
+  for (i = 0; i < 10; i++) {
+    int rv;
+    ibuf[0] = 0;
+    rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), 2000, 0x0a, 0x0d);
+    if (global_opts.debug_level > 1) {
+      safe_print(strlen(ibuf), ibuf);
+    }
+    if (rv < 0) {
+      if (am_sirf == 0) {
+        if (global_opts.debug_level > 1) {
+          warning(MYNAME ": Attempting sirf mode.\n");
+        }
+        /* This is tacky, we have to change speed
+         * to 9600bps to tell it to speak NMEA at
+         * 4800.
+         */
+        am_sirf = hunt_sirf();
+        if (am_sirf) {
+          i = 0;
+          continue;
+        }
+      }
+      fatal(MYNAME ": No data received on %s.\n", qPrintable(posn_fname));
+    }
+    nmea_parse_one_line(ibuf);
+    if (lt != last_read_time) {
+      if (last_read_time) {
+        Waypoint* w = curr_waypt;
+
+        lt = last_read_time;
+        curr_waypt = NULL;
+
+        return w;
+      }
+    }
+  }
+  return NULL;
+}
+
+static void
+nmea_wayptpr(const Waypoint* wpt)
+{
+  char obuf[200];
+  double lat,lon;
+  QString s;
+  int cksum;
+
+  lat = degrees2ddmm(wpt->latitude);
+  lon = degrees2ddmm(wpt->longitude);
+  if (global_opts.synthesize_shortnames) {
+    s = mkshort_from_wpt(mkshort_handle, wpt);
+  } else {
+    s = mkshort(mkshort_handle, wpt->shortname);
+  }
+
+  snprintf(obuf, sizeof(obuf),  "GPWPL,%08.3f,%c,%09.3f,%c,%s",
+           fabs(lat), lat < 0 ? 'S' : 'N',
+           fabs(lon), lon < 0 ? 'W' : 'E', CSTRc(s)
+          );
+  cksum = nmea_cksum(obuf);
+  gbfprintf(file_out, "$%s*%02X\n", obuf, cksum);
+  if (sleepus >= 0) {
+    gbfflush(file_out);
+    gb_sleep(sleepus);
+  }
+}
+void
+nmea_track_init(const route_head*)
+{
+  last_time = -1;
+}
+
+void
+nmea_trackpt_pr(const Waypoint* wpt)
+{
+  char obuf[200];
+  char fix='0';
+  double lat,lon;
+  int cksum;
+  struct tm* tm;
+  time_t hms;
+  time_t ymd;
+
+  if (opt_sleep) {
+    gbfflush(file_out);
+    if (last_time > 0) {
+      if (sleepus >= 0) {
+        gb_sleep(sleepus);
+      } else {
+        long wait_time = wpt->GetCreationTime().toTime_t() - last_time;
+        if (wait_time > 0) {
+          gb_sleep(wait_time * 1000000);
+        }
+      }
+    }
+    last_time = wpt->GetCreationTime().toTime_t();
+  }
+
+  lat = degrees2ddmm(wpt->latitude);
+  lon = degrees2ddmm(wpt->longitude);
+
+  time_t ct = wpt->GetCreationTime().toTime_t();
+  tm = gmtime(&ct);
+  if (tm) {
+    hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec;
+    ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year;
+  } else {
+    hms = 0;
+    ymd = 0;
+  }
+
+  switch (wpt->fix) {
+  case fix_dgps:
+    fix='2';
+    break;
+  case fix_3d:
+  case fix_2d:
+    fix='1';
+    break;
+  case fix_pps:
+    fix='3';
+    break;
+  default:
+    fix='0';
+  }
+
+  if (opt_gprmc) {
+    snprintf(obuf, sizeof(obuf), "GPRMC,%010.3f,%c,%08.3f,%c,%09.3f,%c,%.2f,%.2f,%06d,,",
+             (double) hms + (wpt->GetCreationTime().time().msec() / 1000.0),
+             fix=='0' ? 'V' : 'A',
+             fabs(lat), lat < 0 ? 'S' : 'N',
+             fabs(lon), lon < 0 ? 'W' : 'E',
+             WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0),
+             WAYPT_HAS(wpt, course) ? (wpt->course):(0),
+             (int) ymd);
+    cksum = nmea_cksum(obuf);
+
+    /* GISTeq doesn't care about the checksum, but wants this prefixed, so
+     * we can write it with abandon.
+        */
+    if (opt_gisteq) {
+      gbfprintf(file_out, "---,");
+    }
+    gbfprintf(file_out, "$%s*%02X\n", obuf, cksum);
+  }
+  if (opt_gpgga) {
+    snprintf(obuf, sizeof(obuf), "GPGGA,%010.3f,%08.3f,%c,%09.3f,%c,%c,%02d,%.1f,%.3f,M,%.1f,M,,",
+             (double) hms + (wpt->GetCreationTime().time().msec() / 1000.0),
+             fabs(lat), lat < 0 ? 'S' : 'N',
+             fabs(lon), lon < 0 ? 'W' : 'E',
+             fix,
+             (wpt->sat>0)?(wpt->sat):(0),
+             (wpt->hdop>0)?(wpt->hdop):(0.0),
+             wpt->altitude == unknown_alt ? 0 : wpt->altitude,
+             WAYPT_HAS(wpt, geoidheight)? (wpt->geoidheight) : (0)); /* TODO: we could look up the geoidheight if needed */
+    cksum = nmea_cksum(obuf);
+    gbfprintf(file_out, "$%s*%02X\n", obuf, cksum);
+  }
+  if ((opt_gpvtg) && (WAYPT_HAS(wpt, course) || WAYPT_HAS(wpt, speed))) {
+    snprintf(obuf,sizeof(obuf),"GPVTG,%.3f,T,0,M,%.3f,N,%.3f,K",
+             WAYPT_HAS(wpt, course) ? (wpt->course):(0),
+             WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0),
+             WAYPT_HAS(wpt, speed) ? MPS_TO_KPH(wpt->speed):(0));
+
+    cksum = nmea_cksum(obuf);
+    gbfprintf(file_out, "$%s*%02X\n", obuf, cksum);
+  }
+
+  if ((opt_gpgsa) && (wpt->fix!=fix_unknown)) {
+
+    switch (wpt->fix) {
+    case fix_dgps:
+      /* or */
+    case fix_3d:
+      fix='3';
+      break;
+    case fix_2d:
+      fix='2';
+      break;
+    default:
+      fix=0;
+    }
+    snprintf(obuf,sizeof(obuf),"GPGSA,A,%c,,,,,,,,,,,,,%.1f,%.1f,%.1f",
+             fix,
+             (wpt->pdop>0)?(wpt->pdop):(0),
+             (wpt->hdop>0)?(wpt->hdop):(0),
+             (wpt->vdop>0)?(wpt->vdop):(0));
+    cksum = nmea_cksum(obuf);
+    gbfprintf(file_out, "$%s*%02X\n", obuf, cksum);
+  }
+  gbfflush(file_out);
+}
+
+static void
+nmea_write(void)
+{
+  waypt_disp_all(nmea_wayptpr);
+  track_disp_all(nmea_track_init, NULL, nmea_trackpt_pr);
+}
+
+static void
+nmea_wr_posn_init(const QString& fname)
+{
+  nmea_wr_init(fname);
+}
+
+static void
+nmea_wr_posn(Waypoint* wpt)
+{
+  nmea_trackpt_pr(wpt);
+}
+
+static void
+nmea_wr_posn_deinit(void)
+{
+//     nmea_wr_deinit();
+}
+
+
+ff_vecs_t nmea_vecs = {
+  ff_type_file,
+  {
+    (ff_cap)(ff_cap_read | ff_cap_write),
+    (ff_cap)(ff_cap_read | ff_cap_write),
+    ff_cap_none
+  },
+  nmea_rd_init,
+  nmea_wr_init,
+  nmea_rd_deinit,
+  nmea_wr_deinit,
+  nmea_read,
+  nmea_write,
+  NULL,
+  nmea_args,
+  CET_CHARSET_ASCII, 0,        /* CET-REVIEW */
+  {
+    nmea_rd_posn_init, nmea_rd_posn, nmea_rd_deinit,
+    nmea_wr_posn_init, nmea_wr_posn, nmea_wr_posn_deinit
+  }
+};
+
+/*
+ * If we later decide to implement a "real" Sirf module, this code should
+ * go there.  For now, we try a kind of heavy handed thing - if we don't
+ * see NMEA-isms from the device, we'll go on the premise that it MAY be
+ * a SiRF Star device and send it the "speak NMEA, please" command.
+ */
+
+static void
+sirf_write(unsigned char* buf)
+{
+  int i, chksum = 0;
+  int len = buf[2] << 8 | buf[3];
+
+  for (i = 0; i < len; i++) {
+    chksum += buf[4 + i];
+  }
+  chksum &= 0x7fff;
+
+  buf[len + 4] = chksum  >> 8;
+  buf[len + 5] = chksum  & 0xff;
+
+  gbser_write(gbser_handle, buf, len + 8);  /* 4 at front, 4 at back */
+}
+
+static
+void reset_sirf_to_nmea(int br)
+{
+  static unsigned char pkt[] = {0xa0, 0xa2, 0x00, 0x18,
+                                0x81, 0x02,
+                                0x01, 0x01, /* GGA */
+                                0x00, 0x00, /* suppress GLL */
+                                0x01, 0x00, /* suppress GSA */
+                                0x05, 0x00, /* suppress GSV */
+                                0x01, 0x01, /* use RMC for date*/
+                                0x00, 0x00, /* suppress VTG */
+                                0x00, 0x01, /* output rate */
+                                0x00, 0x01, /* unused recommended values */
+                                0x00, 0x01,
+                                0x00, 0x01, /* ZDA */
+                                0x12, 0xc0, /* 4800 bps */
+                                0x00, 0x00,  /* checksum */
+                                0xb0, 0xb3
+                               }; /* packet end */
+  /* repopulate bit rate */
+  pkt[26] = br >> 8;
+  pkt[27] = br & 0xff;
+
+  sirf_write(pkt);
+  gb_sleep(250 * 1000);
+  gbser_flush(gbser_handle);
+}
diff --git a/nmn4.cc b/nmn4.cc
index e466da29130137019a47d325faae436495a665d1..72f47e910490d79f3a4ede9d14bf1da57a278dda 100644 (file)
--- a/nmn4.cc
+++ b/nmn4.cc
@@ -43,7 +43,7 @@ static char* index_opt;
 
 static
 arglist_t nmn4_args[] = {
-  {"index", &index_opt, "Index of route to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL },
+  {"index", &index_opt, "Index of route to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL , nullptr},
   ARG_TERMINATOR
 };
 
@@ -183,13 +183,13 @@ nmn4_read_data(void)
 }
 
 static void
-nmn4_route_hdr(const route_head* route)
+nmn4_route_hdr(const route_head*)
 {
   curr_rte_num++;
 }
 
 static void
-nmn4_route_tlr(const route_head* rte)
+nmn4_route_tlr(const route_head*)
 {
 }
 
@@ -292,4 +292,6 @@ ff_vecs_t nmn4_vecs = {
   NULL,
   nmn4_args,
   CET_CHARSET_MS_ANSI, 1       /* CET-REVIEW */
+  , NULL_POS_OPS,
+  nullptr
 };
index 0190d9d6d93b74e1cc9cedc5ba2734ed7cfa594d..df56a259033955f658c5a2625607c6aeb3194362 100644 (file)
@@ -32,15 +32,15 @@ static
 arglist_t nuke_args[] = {
   {
     "waypoints", &nukewpts, "Remove all waypoints from data stream",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX
+    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   } ,
   {
     "tracks", &nuketrks, "Remove all tracks from data stream",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX
+    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   } ,
   {
     "routes", &nukertes, "Remove all routes from data stream",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX
+    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
   } ,
   ARG_TERMINATOR
 };